网络流套主席树。

题目链接:http://contesthunter.org/contest/Beta%20Round%20%EF%BC%836%20(%E3%80%8C%E6%80%9D%E8%80%83%E7%86%8A%E3%80%8D%E6%9D%AF%20NOI%E6%A8%A1%E6%8B%9F%E8%B5%9B%20)/A%20%EF%BC%8B%20B%20Problem

 

这是一次模拟赛vfleaking大神出的题目,网络流套主席树。。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long ll;
#define inf 0x3fffffff
int n;
#define N 520000
int e[N],v[N],ne[N],u[N];
int nn=1;
void add(int x,int y,int uu){
    ne[++nn]=e[x],e[x]=nn,v[nn]=y,u[nn]=uu;
}
void Add(int x,int y,int uu){
//    cout<<"ADD"<<x<<" "<<y<<" "<<uu<<endl;
   add(x,y,uu);
   add(y,x,0);    
}
int ta[N],tb[N];
int nod[6000];
struct P{
    int a,b,w,l,r,p;
    int id;
    bool operator<(P x)const{
       return a<x.a;    
    }
}B[6000],C[6000];
int in[6000];
int tot;
ll ans;
int change(int p,int L,int R,int l){
         int k=++tot;
         ta[k]=ta[p],tb[k]=tb[p];
         if(L==R){
            Add(C[l].id*2-1,k,inf);
               return k;
        }
        int m=L+R>>1;
        if(m>=l)ta[k]=change(ta[k],L,m,l);
        else tb[k]=change(tb[k],m+1,R,l);
        if(ta[k])Add(ta[k],k,inf);
        if(tb[k])Add(tb[k],k,inf);
        return k;
}
void Ask(int l,int r,int k,int L,int R,int p){
    if(!k)return;
    if(L>=l&&R<=r){
        Add(k,p,inf);
       return;    
    }
    int m=L+R>>1;
    if(L<=r&&l<=m)Ask(l,r,ta[k],L,m,p);
    if(m+1<=r&&l<=R)Ask(l,r,tb[k],m+1,R,p);
}
int S,T;
int ch[N];
int q[N],he,bo;
int zeng(int x,int mm){
    if(x==T)return mm;
    int k,r=mm;
    for(int i=e[x];i&&r;i=ne[i])if(ch[v[i]]==ch[x]+1&&u[i]){
       k=zeng(v[i],min(r,u[i]));
       u[i]-=k;
       u[i^1]+=k;
       r-=k;
    }
    if(mm==r)ch[x]=-1;
    return mm-r;
}
bool bfs(){
    int x;
    q[he=bo=1]=S;
    for(int i=1;i<=T;i++)ch[i]=-1;
    ch[S]=0;
    while(he>=bo){
           x=q[bo++];
           for(int i=e[x];i;i=ne[i])if(ch[v[i]]==-1&&u[i]){
             ch[v[i]]=ch[x]+1;
             q[++he]=v[i];        
        }
    }
    return ch[T]!=-1;    
}
ll dinic(){
    int tt;
    ll r=0;
    while(bfs())while(tt=zeng(S,inf))r+=tt;
    return r;    
}
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
       scanf("%d%d%d%d%d%d",&B[i].a,&B[i].b,&B[i].w,&B[i].l,&B[i].r,&B[i].p);    
       C[i]=B[i];
       C[i].id=i;
       ans+=B[i].b+B[i].w;
    }
        tot=n*2;
    sort(C+1,C+n+1);
    for(int i=1;i<=n;i++)in[C[i].id]=i;
    for(int i=1;i<=n;i++){
        nod[i]=change(nod[i-1],1,n,in[i]);
    }

    /*for(int i=1;i<=n;i++){
       cout<<C[i].a<<" ";    
    }
    cout<<endl;*/
    for(int i=1;i<=n;i++){
       int ll=0,rr=n+1;
      //     cout<<"i="<<i<<" ";
           while(ll+1!=rr){
          int mid=ll+rr>>1;
          if(C[mid].a>=B[i].l)rr=mid;
          else ll=mid;        
        }
        int L=rr,R;
        ll=0,rr=n+1;
        while(ll+1!=rr){
           int mid=ll+rr>>1;
           if(C[mid].a<=B[i].r)ll=mid;
           else rr=mid;    
        }
        R=ll;
    //    cout<<L<<" "<<R<<endl;
        if(R>=L)Ask(L,R,nod[i-1],1,n,i*2);
    }
    S=tot+1;
    T=S+1;
    for(int i=1;i<=n;i++)Add(S,i*2-1,B[i].w),Add(i*2-1,T,B[i].b),Add(i*2,i*2-1,B[i].p);
    ans-=dinic();
    cout<<ans;
}
posted @ 2014-07-19 22:57  wangyucheng  阅读(185)  评论(0编辑  收藏  举报