• HDU 3397 双lazy标记的问题


    题目大意

    对一个只有0和1的序列,支持以下几种操作
    1.将区间所有的值变成1
    2.将区间所有的值变为0
    3.将区间的0和1翻转(0变成1 1变成0)
    4.求区间中1的个数
    5.求区间连续最长的1的个数

    http://vjudge.net/problem/viewProblem.action?id=14689

    整整一下午。。。简直把自己修改的都要哭了

    lazy标记有先后关系,如to[]覆盖后,那么rev[]翻转标记就应该重新赋为0

    我们在pushdown中,是对孩子节点进行更新,那么更新的也是孩子节点的lazy标记,to[]覆盖的也是孩子节点的标记,对于还没用过的rev[cur]是不用变的,

    这是它父亲传下来的,确保了正确性的

    而在update函数中,每次给to[cur]进行了赋值,那么rev[cur]就要重置为0,因为我们这是对当前节点传入的标记,覆盖执行在当前节点上

    PS:就是这破玩意改了我一下午的时间

    void update(int cur,int x,int y,int s,int t,int op)
    {
        int mid=(x+y)/2,ls=cur<<1,rs=cur<<1|1;
        if(x>=s&&y<=t){
            if(op==0){
                lc[cur][0]=rc[cur][0]=mc[cur][0]=y-x+1;
                lc[cur][1]=rc[cur][1]=mc[cur][1]=0;
                sum[cur]=0;
                to[cur]=0,rev[cur]=0;
            }
            else if(op==1){
                lc[cur][0]=rc[cur][0]=mc[cur][0]=0;
                lc[cur][1]=rc[cur][1]=mc[cur][1]=y-x+1;
                sum[cur]=y-x+1;
                to[cur]=1,rev[cur]=0;
            }
            else if(op==2){
                swap(lc[cur][0],lc[cur][1]);
                swap(rc[cur][0],rc[cur][1]);
                swap(mc[cur][0],mc[cur][1]);
                sum[cur]=y-x+1-sum[cur];
                rev[cur]^=1;
            }
            return;
        }
        push_down(cur,x,y);
        if(mid>=s) update(L,s,t,op);
        if(mid+1<=t) update(R,s,t,op);
        push_up(cur,x,y);
    }

    总代码如下:

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <algorithm>
      4 using namespace std;
      5 #define L ls,x,mid
      6 #define R rs,mid+1,y
      7 #define N 100010
      8 int to[N<<2],rev[N<<2],lc[N<<2][2],rc[N<<2][2],mc[N<<2][2],sum[N<<2],X[N];
      9 void push_up(int cur,int x,int y)
     10 {
     11     int mid=(x+y)/2,ls=cur<<1,rs=cur<<1|1;
     12     sum[cur]=sum[ls]+sum[rs];
     13     for(int i=0;i<2;i++){
     14         lc[cur][i]=lc[ls][i],rc[cur][i]=rc[rs][i];
     15         mc[cur][i]=max(mc[ls][i],mc[rs][i]);
     16         mc[cur][i]=max(mc[cur][i],rc[ls][i]+lc[rs][i]);
     17         if(lc[ls][i]==mid-x+1) lc[cur][i]=lc[ls][i]+lc[rs][i];
     18         if(rc[rs][i]==y-mid) rc[cur][i]=rc[ls][i]+rc[rs][i];
     19     }
     20 }
     21 void push_down(int cur,int x,int y)
     22 {
     23     int mid=(x+y)/2,ls=cur<<1,rs=cur<<1|1;
     24     if(to[cur]!=-1){
     25         to[ls]=to[rs]=to[cur];
     26         rev[ls]=rev[rs]=0;
     27         lc[ls][0]=rc[ls][0]=mc[ls][0]=to[cur]?0:mid-x+1;
     28         lc[ls][1]=rc[ls][1]=mc[ls][1]=to[cur]?mid-x+1:0;
     29         lc[rs][0]=rc[rs][0]=mc[rs][0]=to[cur]?0:y-mid;
     30         lc[rs][1]=rc[rs][1]=mc[rs][1]=to[cur]?y-mid:0;
     31         sum[ls]=to[cur]*(mid-x+1);
     32         sum[rs]=to[cur]*(y-mid);
     33         to[cur]=-1;
     34     }
     35     if(rev[cur]){
     36         rev[ls]^=1,rev[rs]^=1;
     37         swap(lc[ls][0],lc[ls][1]);
     38         swap(lc[rs][0],lc[rs][1]);
     39 
     40         swap(rc[ls][0],rc[ls][1]);
     41         swap(rc[rs][0],rc[rs][1]);
     42 
     43         swap(mc[ls][0],mc[ls][1]);
     44         swap(mc[rs][0],mc[rs][1]);
     45 
     46         sum[ls]=mid-x+1-sum[ls];
     47         sum[rs]=y-mid-sum[rs];
     48 
     49         rev[cur]=0;
     50     }
     51 }
     52 void build(int cur,int x,int y)
     53 {
     54     int mid=(x+y)/2,ls=cur<<1,rs=cur<<1|1;
     55     to[cur]=-1,rev[cur]=0;
     56     if(x==y){
     57         lc[cur][1]=rc[cur][1]=mc[cur][1]=sum[cur]=X[x];
     58         lc[cur][0]=rc[cur][0]=mc[cur][0]=X[x]^1;
     59         //printf("%d
    ",mc[cur][0]);
     60         return;
     61     }
     62     build(L);
     63     build(R);
     64     push_up(cur,x,y);
     65 }
     66 void update(int cur,int x,int y,int s,int t,int op)
     67 {
     68     int mid=(x+y)/2,ls=cur<<1,rs=cur<<1|1;
     69     if(x>=s&&y<=t){
     70         if(op==0){
     71             lc[cur][0]=rc[cur][0]=mc[cur][0]=y-x+1;
     72             lc[cur][1]=rc[cur][1]=mc[cur][1]=0;
     73             sum[cur]=0;
     74             to[cur]=0,rev[cur]=0;
     75         }
     76         else if(op==1){
     77             lc[cur][0]=rc[cur][0]=mc[cur][0]=0;
     78             lc[cur][1]=rc[cur][1]=mc[cur][1]=y-x+1;
     79             sum[cur]=y-x+1;
     80             to[cur]=1,rev[cur]=0;
     81         }
     82         else if(op==2){
     83             swap(lc[cur][0],lc[cur][1]);
     84             swap(rc[cur][0],rc[cur][1]);
     85             swap(mc[cur][0],mc[cur][1]);
     86             sum[cur]=y-x+1-sum[cur];
     87             rev[cur]^=1;
     88         }
     89         return;
     90     }
     91     push_down(cur,x,y);
     92     if(mid>=s) update(L,s,t,op);
     93     if(mid+1<=t) update(R,s,t,op);
     94     push_up(cur,x,y);
     95 }
     96 void query1(int cur,int x,int y,int s,int t,int &ans)
     97 {
     98     int mid=(x+y)/2,ls=cur<<1,rs=cur<<1|1;
     99     if(x>=s&&y<=t){
    100         ans+=sum[cur];
    101         return;
    102     }
    103     push_down(cur,x,y);
    104     if(mid>=s) query1(L,s,t,ans);
    105     if(mid+1<=t) query1(R,s,t,ans);
    106 }
    107 int query2(int cur,int x,int y,int s,int t)
    108 {
    109     int mid=(x+y)/2,ls=cur<<1,rs=cur<<1|1;
    110     if(x>=s&&y<=t){
    111         return mc[cur][1];
    112     }
    113     push_down(cur,x,y);
    114     int ans=0;
    115     if(mid>=s) ans=max(ans,query2(L,s,t));
    116     if(mid+1<=t) ans=max(ans,query2(R,s,t));
    117     return max(ans,min(mid-s+1,rc[ls][1])+min(t-mid,lc[rs][1]));
    118 }
    119 int main()
    120 {
    121     int T,n,m,op,a,b;
    122     scanf("%d",&T);
    123     while(T--){
    124         scanf("%d%d",&n,&m);
    125         for(int i=1;i<=n;i++) scanf("%d",&X[i]);
    126         build(1,1,n);
    127         for(int i=0;i<m;i++){
    128             scanf("%d%d%d",&op,&a,&b);
    129             if(op==3){
    130                 int ans=0;
    131                 query1(1,1,n,a+1,b+1,ans);
    132                 printf("%d
    ",ans);
    133             }
    134             else if(op==4){
    135                 printf("%d
    ",query2(1,1,n,a+1,b+1));
    136             }
    137             else update(1,1,n,a+1,b+1,op);
    138         }
    139     }
    140     return 0;
    141 }
  • 相关阅读:
    P2P理财友情提示
    P2P理财友情提示
    如何在Chrome development tool里查看C4C前台发送的请求细节
    CRM和ERP的Sales Organization的映射关系
    如何从ERP将Material的Batch信息下载到CRM并存储在settype COMM_PR_BATCH里
    CRM中间件里的发布-订阅者模式
    CRM订单状态的Open, In process和Completed这些条目是从哪里来的
    如何证明CRM WebClient UI上的应用是有状态(Stateful)的
    如何使用代码获得一个function module的Where Used List
    观察者模式在One Order回调函数中的应用
  • 原文地址:https://www.cnblogs.com/CSU3901130321/p/3899747.html
Copyright © 2020-2023  润新知