程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> BZOJ 3218(a + b Problem-二分圖套值域線段樹)

BZOJ 3218(a + b Problem-二分圖套值域線段樹)

編輯:C++入門知識

 

 

 

 


出這題的人是怎麼想出來的……

言歸正傳,這題是二分圖套值域線段樹。

首先經過 @Vfleaking的神奇建圖後,把圖拆成二分圖,

不妨利用有向圖最小割的性質建圖(以前我一直以為最小割和邊的方向無關,可這樣的話很奇怪哦……)

理解悲劇……

我們可以利用邊有向的性質解決黑白色塊……

然後發現線段樹很多……主席樹閃亮登場

然後·就這麽A了?…………


[cpp]
#include<cstdio>  
#include<cstdlib>  
#include<cstring>  
#include<iostream>  
#include<algorithm>  
#include<functional>  
#include<cmath>  
#include<cctype>  
using namespace std; 
#define For(i,n) for(int i=1;i<=n;i++)  
#define Rep(i,n) for(int i=0;i<n;i++)  
#define Fork(i,k,n) for(int i=k;i<=n;i++)  
#define ForD(i,n) for(int i=n;i;i--)  
#define Forp(x) for(int p=pre[x];p;p=next[p])  
#define RepD(i,n) for(int i=n;i>=0;i--)  
#define MEM(a) memset(a,0,sizeof(a))  
#define MEMI(a) memset(a,127,sizeof(a))  
#define MEMi(a) memset(a,128,sizeof(a))  
#define INF (2139062143)  
#define MAXN (500000 +10)  
#define MAXM (500000 +10)  
int n,m,s,t; 
int edge[MAXM],next[MAXM]={0},pre[MAXN]={0},weight[MAXM],size=1; 
void addedge(int u,int v,int w) 

    edge[++size]=v; 
    weight[size]=w; 
    next[size]=pre[u]; 
    pre[u]=size; 

void addedge2(int u,int v,int w){/*cout<<u<<' '<<v<<' '<<w<<endl;*/addedge(u,v,w),addedge(v,u,0);} 
int cnt[MAXN]={0},d[MAXN]={0}; 
long long totflow=0; 
long long sap(int x,int flow) 

    if (x==t) return flow; 
    int nowflow=0; 
    Forp(x) 
    { 
        int &v=edge[p]; 
        if (d[v]==d[x]-1&&weight[p]) 
        { 
            long long fl=sap(v,min(weight[p],flow)); 
            weight[p]-=fl,weight[p^1]+=fl,nowflow+=fl,flow-=fl; 
            if (!flow) return nowflow; 
        } 
    }    
    if (!(--cnt[d[x]++])) d[s]=t+1; 
    cnt[d[x]]++; 
    return nowflow; 

struct node 

    node *ch[2]; 
    node(){ch[0]=ch[1]=NULL;} 
}q[MAXN],*root[MAXN]={NULL}; 
int tail=0; 
void ins(node *&p,node *x,int l,int r,int c) 

    int m=(l+r) >>1; 
    p=&q[++tail]; 
    if (x) *p=*x; 
    if (l==r) return; 
    if (c<=m) ins(p->ch[0],p->ch[0],l,m,c); 
    else ins(p->ch[1],p->ch[1],m+1,r,c);       

void print(node *p) 

    //cout<<  

node *ans[MAXN]; 
int ans_siz=0; 
void qur(node *p,int l,int r,int L,int R) 

    if (!p||L>R) return; 
    int m=l+r >>1; 
    if (L<=l&&r<=R) {ans[++ans_siz]=p;return;} 
    if (l==r) return; 
    if (L<=m) qur(p->ch[0],l,m,L,R); 
    if (m<R) qur(p->ch[1],m+1,r,L,R); 

int a2[MAXN],a[MAXN],b[MAXN],w[MAXN],l[MAXN],r[MAXN],p[MAXN]; 
int main() 

    freopen("bzoj3218.in","r",stdin); 
//  freopen(".out","w",stdout);  
    scanf("%d",&n); 
    For(i,n) scanf("%d%d%d%d%d%d",&a[i],&b[i],&w[i],&l[i],&r[i],&p[i]); 
    memcpy(a2,a,sizeof(a)); 
    sort(a2+1,a2+n+1); 
    int size=unique(a2+1,a2+n+1)-(a2+1); 
    For(i,n)  
    { 
        a[i]=lower_bound(a2+1,a2+size+1,a[i])-(a2); 
        l[i]=lower_bound(a2+1,a2+size+1,l[i])-(a2); 
        r[i]=upper_bound(a2+1,a2+size+1,r[i])-(a2)-1; 
    } 
    For(i,n) ins(root[i],root[i-1],1,size,a[i]); 
     
    s=2*n+1; t=2*n+2; 
    For(i,n) addedge2(s,i,b[i]),addedge2(i,t,w[i]),addedge2(i,n+i,p[i]); 
    For(i,tail) 
    { 
        if (q[i].ch[0]) addedge2(t+i,t+((q[i].ch[0])-q),INF); 
        if (q[i].ch[1]) addedge2(t+i,t+((q[i].ch[1])-q),INF); 
    } 
    For(i,n) 
    { 
        ans_siz=0; 
        qur(root[i],1,size,a[i],a[i]); 
        qur(root[i-1],1,size,a[i],a[i]); 
        node *cur=ans[1],*last=NULL; 
        if (ans_siz>1) last=ans[2]; 
        //cout<<t+((cur)-(q))<<'*';  
        addedge2(t+((cur)-(q)),i,INF); 
         
        if (ans_siz>1) addedge2(t+(cur-(q)),t+((last)-(q)),INF); 
    } 
    For(i,n) 
    { 
        ans_siz=0; 
        qur(root[i],1,size,l[i],r[i]); 
        For(j,ans_siz) addedge2(n+i,t+((ans[j])-(q)),INF); 
    }    
    //cout<<2*n+2+tail<<endl;     
    cnt[0]=2*n+2+tail; 
    while (d[s]<=t) {totflow+=sap(s,INF);}  
    //For(i,2*n+tail) cout<<d[i]<<' ';  
    long long ans=-totflow; 
    For(i,n) ans+=b[i]+w[i]; 
    cout/*<<totflow<<' '*/<<ans<<endl;   
     
    return 0; 

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<functional>
#include<cmath>
#include<cctype>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define Forp(x) for(int p=pre[x];p;p=next[p])
#define RepD(i,n) for(int i=n;i>=0;i--)
#define MEM(a) memset(a,0,sizeof(a))
#define MEMI(a) memset(a,127,sizeof(a))
#define MEMi(a) memset(a,128,sizeof(a))
#define INF (2139062143)
#define MAXN (500000 +10)
#define MAXM (500000 +10)
int n,m,s,t;
int edge[MAXM],next[MAXM]={0},pre[MAXN]={0},weight[MAXM],size=1;
void addedge(int u,int v,int w)
{
 edge[++size]=v;
 weight[size]=w;
 next[size]=pre[u];
 pre[u]=size;
}
void addedge2(int u,int v,int w){/*cout<<u<<' '<<v<<' '<<w<<endl;*/addedge(u,v,w),addedge(v,u,0);}
int cnt[MAXN]={0},d[MAXN]={0};
long long totflow=0;
long long sap(int x,int flow)
{
 if (x==t) return flow;
 int nowflow=0;
 Forp(x)
 {
  int &v=edge[p];
  if (d[v]==d[x]-1&&weight[p])
  {
   long long fl=sap(v,min(weight[p],flow));
   weight[p]-=fl,weight[p^1]+=fl,nowflow+=fl,flow-=fl;
   if (!flow) return nowflow;
  }
 } 
 if (!(--cnt[d[x]++])) d[s]=t+1;
 cnt[d[x]]++;
 return nowflow;
}
struct node
{
 node *ch[2];
 node(){ch[0]=ch[1]=NULL;}
}q[MAXN],*root[MAXN]={NULL};
int tail=0;
void ins(node *&p,node *x,int l,int r,int c)
{
 int m=(l+r) >>1;
 p=&q[++tail];
 if (x) *p=*x;
 if (l==r) return;
 if (c<=m) ins(p->ch[0],p->ch[0],l,m,c);
 else ins(p->ch[1],p->ch[1],m+1,r,c);  
}
void print(node *p)
{
 //cout<<
}
node *ans[MAXN];
int ans_siz=0;
void qur(node *p,int l,int r,int L,int R)
{
 if (!p||L>R) return;
 int m=l+r >>1;
 if (L<=l&&r<=R) {ans[++ans_siz]=p;return;}
 if (l==r) return;
 if (L<=m) qur(p->ch[0],l,m,L,R);
 if (m<R) qur(p->ch[1],m+1,r,L,R);
}
int a2[MAXN],a[MAXN],b[MAXN],w[MAXN],l[MAXN],r[MAXN],p[MAXN];
int main()
{
 freopen("bzoj3218.in","r",stdin);
// freopen(".out","w",stdout);
 scanf("%d",&n);
 For(i,n) scanf("%d%d%d%d%d%d",&a[i],&b[i],&w[i],&l[i],&r[i],&p[i]);
 memcpy(a2,a,sizeof(a));
 sort(a2+1,a2+n+1);
 int size=unique(a2+1,a2+n+1)-(a2+1);
 For(i,n)
 {
  a[i]=lower_bound(a2+1,a2+size+1,a[i])-(a2);
  l[i]=lower_bound(a2+1,a2+size+1,l[i])-(a2);
  r[i]=upper_bound(a2+1,a2+size+1,r[i])-(a2)-1;
 }
 For(i,n) ins(root[i],root[i-1],1,size,a[i]);
 
 s=2*n+1; t=2*n+2;
 For(i,n) addedge2(s,i,b[i]),addedge2(i,t,w[i]),addedge2(i,n+i,p[i]);
 For(i,tail)
 {
  if (q[i].ch[0]) addedge2(t+i,t+((q[i].ch[0])-q),INF);
  if (q[i].ch[1]) addedge2(t+i,t+((q[i].ch[1])-q),INF);
 }
 For(i,n)
 {
  ans_siz=0;
  qur(root[i],1,size,a[i],a[i]);
  qur(root[i-1],1,size,a[i],a[i]);
  node *cur=ans[1],*last=NULL;
  if (ans_siz>1) last=ans[2];
  //cout<<t+((cur)-(q))<<'*';
  addedge2(t+((cur)-(q)),i,INF);
  
  if (ans_siz>1) addedge2(t+(cur-(q)),t+((last)-(q)),INF);
 }
 For(i,n)
 {
  ans_siz=0;
  qur(root[i],1,size,l[i],r[i]);
  For(j,ans_siz) addedge2(n+i,t+((ans[j])-(q)),INF);
 } 
 //cout<<2*n+2+tail<<endl; 
 cnt[0]=2*n+2+tail;
 while (d[s]<=t) {totflow+=sap(s,INF);}
 //For(i,2*n+tail) cout<<d[i]<<' ';
 long long ans=-totflow;
 For(i,n) ans+=b[i]+w[i];
 cout/*<<totflow<<' '*/<<ans<<endl; 
 
 return 0;
}

 

 


 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved