zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    Add Two Numbers
    Reverse Linked List II
    Reverse Linked List
    Remove Duplicates from Sorted List
    Remove Duplicates from Sorted List II
    Partition List
    Intersection of Two Linked Lists
    4Sum
    3Sum
    2Sum
  • 原文地址:https://www.cnblogs.com/CSU3901130321/p/3899747.html
Copyright © 2011-2022 走看看