zoukankan      html  css  js  c++  java
  • bzoj 3218 a + b Problem(最小割+主席树)

    【题目链接】

        http://www.lydsy.com/JudgeOnline/problem.php?id=3218

    【题意】

        给n个格子涂白或黑色,白则wi,黑则bi的好看度,若黑格i存在:

            1<=j<I,li<=aj<=ri,格子为白色

        则损失pi,问最大的好看度。

    【思路】

        考虑建立最小割模型:

    1. 首先将一个点拆成两个中间连pi
    2. 连边(S,Xi,wi) (Xi,T,bi)
    3. 对于一个满足i要求的j,连边(Xj,Yi,inf),代表i只有两种选择,一为设白色,一为损失pi。

      这样跑出的最小割即为答案。

      但该图的边数过多,因此需要优化。

      建一棵线段树,由线段树中所有被[li,ri]包含的点向Yi连边inf,由Xi向对应的叶子连边。然后加上j<i的条件,我们需要一棵可持久化线段树,因此需要Yi被T[i-1]的[li,ri]区间连边,Xi向T[i]的叶子连边。这样就成功将边数缩到O(nlogn)级别。

    【代码】

      1 #include<set>
      2 #include<cmath>
      3 #include<queue>
      4 #include<vector>
      5 #include<cstdio>
      6 #include<cstring>
      7 #include<iostream>
      8 #include<algorithm>
      9 #define X(i) (i)
     10 #define Y(i) (i+n)
     11 #define trav(u,i) for(int i=front[u];i;i=e[i].nxt)
     12 #define FOR(a,b,c) for(int a=(b);a<=(c);a++)
     13 using namespace std;
     14 
     15 typedef long long ll;
     16 const int N = 2e5+200;
     17 const int inf = 1e9;
     18 
     19 ll read() {
     20     char c=getchar();
     21     ll f=1,x=0;
     22     while(!isdigit(c)) {
     23         if(c=='-') f=-1; c=getchar();
     24     }
     25     while(isdigit(c))
     26         x=x*10+c-'0',c=getchar();
     27     return x*f;
     28 }
     29 
     30 struct Edge {
     31     int u,v,cap,flow;
     32 };
     33 struct Dinic {
     34     int d[N],cur[N],vis[N];
     35     vector<Edge> es;
     36     vector<int> g[N];
     37     queue<int> q;
     38     
     39     void AddEdge (int u,int v,int w) {
     40         es.push_back((Edge){u,v,w,0});
     41         es.push_back((Edge){v,u,0,0});
     42         int m=es.size();
     43         g[u].push_back(m-2);
     44         g[v].push_back(m-1);
     45     }
     46     bool bfs(int s,int t) {
     47         memset(vis,0,sizeof(vis));
     48         d[s]=0; vis[s]=1;
     49         q.push(s);
     50         while(!q.empty()) {
     51             int u=q.front(); q.pop();
     52             FOR(i,0,(int)g[u].size()-1) {
     53                 Edge& e=es[g[u][i]];
     54                 int v=e.v;
     55                 if(e.cap>e.flow&&!vis[v]) {
     56                     vis[v]=1;
     57                     d[v]=d[u]+1;
     58                     q.push(v);
     59                 }
     60             }
     61         }
     62         return vis[t];
     63     }
     64     int dfs(int u,int a,int t) {
     65         if(u==t||a==0) return a;
     66         int flow=0,f;
     67         for(int& i=cur[u];i<g[u].size();i++) {
     68             Edge& e=es[g[u][i]];
     69             int v=e.v;
     70             if(d[v]==d[u]+1&&(f=dfs(v,min(a,e.cap-e.flow),t))>0) {
     71                 e.flow+=f;
     72                 es[g[u][i]^1].flow-=f;
     73                 flow+=f,a-=f;
     74                 if(!a) break;
     75             }
     76         }
     77         return flow;
     78     }
     79     int maxflow(int s,int t) {
     80         int flow=0;
     81         while(bfs(s,t)) {
     82             memset(cur,0,sizeof(cur));
     83             flow+=dfs(s,inf,t);
     84         }
     85         return flow;
     86     }
     87 } dc;
     88 
     89 int n,cnt;
     90 
     91 struct Tnode {
     92     Tnode *ls,*rs;
     93     int sum,id;
     94     void * operator new (size_t,Tnode* l,Tnode* r) {
     95         static Tnode mempool[N],*G=mempool;
     96         G->ls=l,G->rs=r,G->id=++cnt;
     97         return G++;
     98     }
     99     Tnode* build(int l,int r,int x,int from) {
    100         int mid=l+r>>1;
    101         Tnode *t;
    102         if(l==r)
    103             t=new (0x0,0x0)Tnode;
    104         else if(x<=mid)
    105             t=new (ls->build(l,mid,x,from),rs) Tnode;
    106         else 
    107             t=new (ls,rs->build(mid+1,r,x,from)) Tnode;
    108         dc.AddEdge(from,t->id,inf);
    109         dc.AddEdge(id,t->id,inf);
    110         return t;
    111     }
    112     void Add(int l,int r,int L,int R,int to) {
    113         if(L<=l&&r<=R) {
    114             dc.AddEdge(id,to,inf);
    115         } else {
    116             int mid=l+r>>1;
    117             if(L<=mid&&ls) ls->Add(l,mid,L,R,to);
    118             if(mid<R&&rs) rs->Add(mid+1,r,L,R,to);
    119         }
    120     }
    121     
    122 } *T[5050];
    123 
    124 int hash[N],tot,a[N],b[N],l[N],r[N],p[N],w[N];
    125 
    126 int main()
    127 {
    128     n=read();
    129     cnt=Y(n);
    130     int s=++cnt,t=++cnt;
    131     T[0]=new (0x0,0x0)Tnode;
    132     T[0]->ls=T[0]->rs=T[0];
    133     ll ans=0;
    134     FOR(i,1,n) {
    135         a[i]=read(),b[i]=read(),w[i]=read(),l[i]=read(),r[i]=read(),p[i]=read();
    136         hash[++tot]=a[i],hash[++tot]=l[i],hash[++tot]=r[i];
    137     }
    138     
    139     sort(hash+1,hash+tot+1);
    140     tot=unique(hash+1,hash+tot+1)-hash-1;
    141     FOR(i,1,n) {
    142         a[i]=lower_bound(hash+1,hash+tot+1,a[i])-hash;
    143         l[i]=lower_bound(hash+1,hash+tot+1,l[i])-hash;
    144         r[i]=lower_bound(hash+1,hash+tot+1,r[i])-hash;
    145     }
    146     
    147     FOR(i,1,n) {
    148         ans+=w[i]+b[i];
    149         dc.AddEdge(s,X(i),w[i]);
    150         dc.AddEdge(X(i),t,b[i]);
    151         T[i]=T[i-1]->build(1,tot,a[i],X(i));
    152         T[i-1]->Add(1,tot,l[i],r[i],Y(i));
    153         dc.AddEdge(Y(i),X(i),p[i]);
    154     }
    155     ans-=dc.maxflow(s,t);
    156     printf("%lld
    ",ans);
    157     return 0;
    158 }

    P.S.神的我无力吐槽=-=

  • 相关阅读:
    Codeforces Round #700 (Div. 2)
    2020-2021 ACM-ICPC Brazil Subregional Programming Contest
    Codeforces Round #699 (Div. 2)
    2021牛客寒假算法基础集训营3
    2021牛客寒假算法基础集训营1
    Educational Codeforces Round 103 (Rated for Div. 2)
    Codeforces Round #697 (Div. 3)
    Codeforces Round #696 (Div. 2)
    2017 ECNA Regional Contest
    spring的aop详解
  • 原文地址:https://www.cnblogs.com/lidaxin/p/5330260.html
Copyright © 2011-2022 走看看