zoukankan      html  css  js  c++  java
  • bzoj 3218: a + b Problem

    Description

    Input

    Output

    Sample Input

    Sample Output

    HINT

    Source 

    传说中的可持久化线段树优化网络流。。。

    做了一些预备题后最小割建图还是比较简单,但边数是n^2。

    每次可以通过向值域中的区间连边,使边数降为nlogn,要满足j<i,打一个可持久化,每次搞完再insert即可

    蒯一个PoPoQQQ大爷的图,很清楚啊。。。

    // MADE BY QT666
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<iostream>
    #include<cstring>
    #define RG register
    using namespace std;
    typedef long long ll;
    const int N=1000050;
    const int Inf=19260817;
    int gi(){
      int x=0,flag=1;
      char ch=getchar();
      while(ch<'0'||ch>'9'){if(ch=='-') flag=-1;ch=getchar();}
      while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
      return x*flag;
    }
    int head[N],nxt[N],to[N],s[N],cnt=1,level[N],q[N],S,T,F;
    int a[5050],b[5050],w[5050],l[5050],r[5050],p[5050],n,tot;
    int sz,ls[100050],rs[100050],root[100050],hsh[100050],sum,goal,hh=0;
    inline void Addedge(RG int x,RG int y,RG int z) {
      to[++cnt]=y,s[cnt]=z,nxt[cnt]=head[x],head[x]=cnt;
    }
    inline void lnk(RG int x,RG int y,RG int z){
      if(!x||!y) return;
      Addedge(x,y,z),Addedge(y,x,0);
    }
    inline bool bfs(){
      for(RG int i=1;i<=sz;i++) level[i]=0;
      q[0]=S,level[S]=1;int t=0,sum=1;
      while(t<sum){
        int x=q[t++];
        if(x==T) return 1;
        for(RG int i=head[x];i;i=nxt[i]){
          int y=to[i];
          if(s[i]&&level[y]==0){
    	level[y]=level[x]+1;
    	q[sum++]=y;
          }
        }
      }
      return 0;
    }
    inline int dfs(RG int x,int maxf){
      if(x==T) return maxf;
      int ret=0;
      for(RG int i=head[x];i;i=nxt[i]){
        int y=to[i],f=s[i];
        if(level[y]==level[x]+1&&f){
          int minn=min(f,maxf-ret);
          f=dfs(y,minn);
          s[i]-=f,s[i^1]+=f,ret+=f;
          if(ret==maxf) break;
        }
      }
      if(!ret) level[x]=0;
      return ret;
    }
    inline void Dinic(){
      while(bfs()) F+=dfs(S,Inf);
    }
    inline void insert(int l,int r,int x,int &y,int v){
      y=++sz;ls[y]=ls[x],rs[y]=rs[x];hh++;
        lnk(x,y,Inf);lnk(goal,y,Inf);
        if(l==r) return;
        int mid=(l+r)>>1;
        if(v<=mid) insert(l,mid,ls[x],ls[y],v);
        else insert(mid+1,r,rs[x],rs[y],v);
    }
    inline void query(int x,int L,int R,int xl,int xr){
      if(!x) return;
      if(xl<=L&&R<=xr){lnk(x,goal,Inf);return;}
      int mid=(L+R)>>1;
      if(xl<=mid) query(ls[x],L,mid,xl,xr);
      if(xr>mid) query(rs[x],mid+1,R,xl,xr);
    }
    int main(){
      n=gi();S=2*n+1;T=2*n+2;sz=T;
      for(RG int i=1;i<=n;i++){
        a[i]=gi(),b[i]=gi(),w[i]=gi(),l[i]=gi(),r[i]=gi(),p[i]=gi();
        tot+=b[i],tot+=w[i];hsh[++sum]=a[i];
      }
      sort(hsh+1,hsh+1+sum);sum=unique(hsh+1,hsh+sum+1)-hsh-1;
      for(int i=1;i<=n;i++){
        a[i]=lower_bound(hsh+1,hsh+1+sum,a[i])-hsh;
        l[i]=lower_bound(hsh+1,hsh+1+sum,l[i])-hsh;
        r[i]=upper_bound(hsh+1,hsh+1+sum,r[i])-hsh-1;
        lnk(S,i,w[i]);lnk(i,T,b[i]);lnk(i+n,i,p[i]);
      }
      for(int i=1;i<=n;i++){
        goal=i+n;if(l[i]<=r[i]) query(root[i-1],1,sum,l[i],r[i]);
        goal=i;insert(1,sum,root[i-1],root[i],a[i]);
      }
      Dinic();printf("%d
    ",tot-F);
      return 0;
    }
    

      

  • 相关阅读:
    第二次结对作业(陆桂莺+崔亚明)
    第一次结对作业
    第二次作业:代码互改
    markdown详细
    第一次个人编程作业:我的分数我做主
    手动下载transformers的模型
    torch设置GPU
    Python import的搜索路径和不可以import的解决方法 (On Linux)
    Python中windows路径的3种写法
    一台计算机安装多个版本的torch和CUDA的教程
  • 原文地址:https://www.cnblogs.com/qt666/p/6992486.html
Copyright © 2011-2022 走看看