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

    题解:

    先做60分。。。

    考虑最小割,连边容量为需要付出的代价。不妨设在s割为黑色,t割为白色。

    (s,i,b[i])(i,t,w[i])

    关于奇怪,因为不是按份数来的。所以我们这样建图:

    (i,i+n,p[i])(i+n,j,inf) l[i]<=a[j]<=r[i]

    代表只要有一个j属于t割,那么i+n就会属于t割,而如果i属于s割,就会付出p[i]的代价。

    注意:(x,y,inf)表示x在s割,那么y一定在s割 或者说 y在t割,那么x一定在t割。而有可能出现x在t割,而y在s割的情况。这证实了上面算法的正确性。

    代码:

     1 #include<cstdio>
     2 #include<cstdlib>
     3 #include<cmath>
     4 #include<cstring>
     5 #include<algorithm>
     6 #include<iostream>
     7 #include<vector>
     8 #include<map>
     9 #include<set>
    10 #include<queue>
    11 #include<string>
    12 #define inf 1000000000
    13 #define maxn 1000000+5
    14 #define maxm 1000000+5
    15 #define eps 1e-10
    16 #define ll long long
    17 #define pa pair<int,int>
    18 #define for0(i,n) for(int i=0;i<=(n);i++)
    19 #define for1(i,n) for(int i=1;i<=(n);i++)
    20 #define for2(i,x,y) for(int i=(x);i<=(y);i++)
    21 #define for3(i,x,y) for(int i=(x);i>=(y);i--)
    22 #define for4(i,x) for(int i=head[x],y=e[i].go;i;i=e[i].next,y=e[i].go)
    23 #define mod 1000000007
    24 using namespace std;
    25 inline int read()
    26 {
    27     int x=0,f=1;char ch=getchar();
    28     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    29     while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();}
    30     return x*f;
    31 }
    32 int a[maxn],b[maxn],w[maxn],l[maxn],r[maxn],p[maxn];
    33 int  n,m,s,t,sum,maxflow,tot=1,head[maxn],cur[maxn],h[maxn];
    34 queue<int>q;
    35 struct edge{int go,next,v;}e[maxm];
    36 void add(int x,int y,int v)
    37 {
    38     e[++tot]=(edge){y,head[x],v};head[x]=tot;
    39     e[++tot]=(edge){x,head[y],0};head[y]=tot;
    40 }
    41 bool bfs()
    42 {
    43     for(int i=s;i<=t;i++)h[i]=-1;
    44     q.push(s);h[s]=0;
    45     while(!q.empty())
    46     {
    47         int x=q.front();q.pop();
    48         for(int i=head[x];i;i=e[i].next)
    49          if(e[i].v&&h[e[i].go]==-1)
    50          {
    51             h[e[i].go]=h[x]+1;q.push(e[i].go);
    52          }
    53     }
    54     return h[t]!=-1;
    55 }
    56 int dfs(int x,int f)
    57 {
    58     if(x==t) return f;
    59     int tmp,used=0;
    60     for(int i=cur[x];i;i=e[i].next)
    61      if(e[i].v&&h[e[i].go]==h[x]+1)
    62     {
    63         tmp=dfs(e[i].go,min(e[i].v,f-used));
    64         e[i].v-=tmp;if(e[i].v)cur[x]=i;
    65         e[i^1].v+=tmp;used+=tmp;
    66         if(used==f)return f;       
    67     }
    68     if(!used) h[x]=-1;
    69     return used;
    70 }
    71 void dinic()
    72 {
    73     maxflow=0;
    74     while(bfs())
    75     {
    76         for (int i=s;i<=t;i++)cur[i]=head[i];maxflow+=dfs(s,inf);
    77     }
    78 }
    79 int main()
    80 {
    81     freopen("input.txt","r",stdin);
    82     freopen("output.txt","w",stdout);
    83     n=read();s=0;t=2*n+1;
    84     for1(i,n)a[i]=read(),b[i]=read(),w[i]=read(),l[i]=read(),r[i]=read(),p[i]=read(),sum+=b[i]+w[i];
    85     for1(i,n)
    86     {
    87         add(s,i,b[i]);add(i,t,w[i]);add(i,i+n,p[i]);
    88         for1(j,i-1)if(a[j]>=l[i]&&a[j]<=r[i])add(i+n,j,inf);
    89     }
    90     dinic();
    91     cout<<sum-maxflow<<endl;
    92     return 0;
    93 }
    View Code

     现在考虑满分做法:

    奇怪的格子的约束条件是:存在j<i,且l[i]<=a[j]<=r[i]。

    首先我们先忽略j<i。

    那我们可以先把所有的a[i]插入一棵线段树中,由每个i+n像[l[i],r[i]]所包含的区间连边inf。

    然后每个包含i的区间向 i 连边。

    这样就实现了 s-> i -> i+n -> 线段树的节点(表示区间) -> j -> t

    只不过在原来的算法上多转了几个点。

    然后考虑限制:j<i

    我们想到对每个i,建一棵1-i的线段树,然后执行上面的算法。

    我们想到了可持久化线段树。

    这样就可以解决了。

    需要注意的细节:

    1.离散化

    2.

    如果出现a[i]相同的情况,我们需不需要向每个i连边?

    不需要,如果在前一个版本a[i]出现过,记为last.对于当前版本出现的a[i],记为now

    (now,last,INF)

    这样子,我们可以实现i’通过线段树对所有满足0<j<i,l <= a[j] <= r的点的控制。--谢图图

    代码:真是道好题+神题!!!

      1 #include<cstdio>
      2 #include<cstdlib>
      3 #include<cmath>
      4 #include<cstring>
      5 #include<algorithm>
      6 #include<iostream>
      7 #include<vector>
      8 #include<map>
      9 #include<set>
     10 #include<queue>
     11 #include<string>
     12 #define inf 2000000000
     13 #define maxn 500000+5
     14 #define maxm 500000+5
     15 #define eps 1e-10
     16 #define ll long long
     17 #define pa pair<int,int>
     18 #define for0(i,n) for(int i=0;i<=(n);i++)
     19 #define for1(i,n) for(int i=1;i<=(n);i++)
     20 #define for2(i,x,y) for(int i=(x);i<=(y);i++)
     21 #define for3(i,x,y) for(int i=(x);i>=(y);i--)
     22 #define for4(i,x) for(int i=head[x],y=e[i].go;i;i=e[i].next,y=e[i].go)
     23 #define mod 1000000007
     24 using namespace std;
     25 inline int read()
     26 {
     27     int x=0,f=1;char ch=getchar();
     28     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
     29     while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();}
     30     return x*f;
     31 }
     32 int a[maxn],b[maxn],w[maxn],l[maxn],r[maxn],p[maxn],rt[maxn],ss[maxm],ls[maxm],rs[maxm];
     33 int  n,m,s,t,cnt,maxflow,sum,tot=1,head[maxn],cur[maxn],h[maxn];
     34 queue<int>q;
     35 struct edge{int go,next,v;}e[maxm];
     36 void add(int x,int y,int v)
     37 {
     38     e[++tot]=(edge){y,head[x],v};head[x]=tot;
     39     e[++tot]=(edge){x,head[y],0};head[y]=tot;
     40 }
     41 bool bfs()
     42 {
     43     for(int i=0;i<=cnt;i++)h[i]=-1;
     44     q.push(s);h[s]=0;
     45     while(!q.empty())
     46     {
     47         int x=q.front();q.pop();
     48         for(int i=head[x];i;i=e[i].next)
     49          if(e[i].v&&h[e[i].go]==-1)
     50          {
     51             h[e[i].go]=h[x]+1;q.push(e[i].go);
     52          }
     53     }
     54     return h[t]!=-1;
     55 }
     56 int dfs(int x,int f)
     57 {
     58     if(x==t) return f;
     59     int tmp,used=0;
     60     for(int i=cur[x];i;i=e[i].next)
     61      if(e[i].v&&h[e[i].go]==h[x]+1)
     62     {
     63         tmp=dfs(e[i].go,min(e[i].v,f-used));
     64         e[i].v-=tmp;if(e[i].v)cur[x]=i;
     65         e[i^1].v+=tmp;used+=tmp;
     66         if(used==f)return f;       
     67     }
     68     if(!used) h[x]=-1;
     69     return used;
     70 }
     71 void dinic()
     72 {
     73     maxflow=0;
     74     while(bfs())
     75     {
     76         for (int i=0;i<=cnt;i++)cur[i]=head[i];maxflow+=dfs(s,inf);
     77     }
     78 }
     79 inline void update(int l,int r,int x,int &y,int z,int p)
     80 {
     81     y=++cnt;
     82     ss[y]=ss[x]+1;
     83     add(y,p,inf);
     84     if(x)add(y,x,inf);
     85     if(l==r)return;
     86     ls[y]=ls[x];rs[y]=rs[x];
     87     int mid=(l+r)>>1;
     88     if(z<=mid)update(l,mid,ls[x],ls[y],z,p);
     89     else update(mid+1,r,rs[x],rs[y],z,p);
     90 }    
     91 inline void query(int k,int l,int r,int x,int y,int z)
     92 {
     93     if(!k)return;
     94     if(l==x&&r==y){add(z,k,inf);return;}
     95     int mid=(l+r)>>1;
     96     if(y<=mid)query(ls[k],l,mid,x,y,z);
     97     else if(x>mid)query(rs[k],mid+1,r,x,y,z);
     98     else query(ls[k],l,mid,x,mid,z),query(rs[k],mid+1,r,mid+1,y,z);
     99 }
    100 int main()
    101 {
    102     freopen("input.txt","r",stdin);
    103     freopen("output.txt","w",stdout);
    104     n=read();s=0;t=2*n+1;cnt=t;
    105     for1(i,n)
    106     {
    107        a[i]=b[i]=read();
    108        int x=read(),y=read();
    109        l[i]=read();r[i]=read();
    110        int z=read();
    111        sum+=x+y;
    112        add(s,i,x);add(i,t,y);
    113        add(i,i+n,z);
    114     }
    115     sort(b+1,b+n+1);
    116     for1(i,n)
    117     {
    118         int x=lower_bound(b+1,b+n+1,l[i])-b;
    119         int y=upper_bound(b+1,b+n+1,r[i])-b-1;
    120         int z=lower_bound(b+1,b+n+1,a[i])-b;
    121         if(x<=y)query(rt[i-1],1,n,x,y,i+n);
    122         update(1,n,rt[i-1],rt[i],z,i);
    123     }
    124     dinic();
    125     cout<<sum-maxflow<<endl;
    126     return 0;
    127 }
    View Code

    3218: a + b Problem

    Time Limit: 20 Sec  Memory Limit: 40 MB
    Submit: 426  Solved: 168
    [Submit][Status]

    Description

  • 相关阅读:
    WRF WPS预处理
    CVS安装
    Linux窗口最小化消失,任务栏上无法找到的解决方法
    NCARG安装配置出现error while loading shared libraries: libg2c.so.0问题额解决办法
    Netcdf安装
    Embedding R-generated Interactive HTML pages in MS PowerPoint(转)
    The leaflet package for online mapping in R(转)
    Some 3D Graphics (rgl) for Classification with Splines and Logistic Regression (from The Elements of Statistical Learning)(转)
    What does a Bayes factor feel like?(转)
    Weka算法介绍
  • 原文地址:https://www.cnblogs.com/zyfzyf/p/4197009.html
Copyright © 2011-2022 走看看