zoukankan      html  css  js  c++  java
  • HDU 3397 Sequence operation

    题目意思很简单,四种操作:全部变成1,全部变成0,或者区间异或,查询区间1的个数,和区间连续的1的最大长度。理解起来没有问题,可是写起代码来发现非常繁琐,共用了9个数组,差不多200行了,第一次写这么长得代码,WA一次,后来发现某个地方rt<<1,写成了rt<<1|1,还有PushUp向上更新时忘记了cover[rt]也要根据sum[rt]的值进行更新。

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 #include<cstdlib>
      5 #define N 111111
      6 #define lson l,m,rt<<1
      7 #define rson m+1,r,rt<<1|1
      8 using namespace std;
      9 
     10 int sum[N<<2],msum[N<<2],lsum[N<<2],rsum[N<<2],XOR[N<<2],cover[N<<2],msum0[N<<2],lsum0[N<<2],rsum0[N<<2];
     11 
     12 
     13 //sum表示区间1的个数,msum表示区间连续1的最大长度,lsum表示从左端开始的1的最大长度,
     14 //XOR为异或标记,cover为覆盖标记,1,0表示区间分别被1,0完全覆盖,-1不完全覆盖
     15 //msum0,lsum0,rsum0表示对应的0的个数的统计。
     16 
     17 
     18 void PushUp(int rt,int m)
     19 {
     20     sum[rt]=sum[rt<<1]+sum[rt<<1|1];
     21     cover[rt]=((sum[rt]==m)?1:((sum[rt]==0)?0:-1));
     22     lsum[rt]=lsum[rt<<1];//我擦
     23     rsum[rt]=rsum[rt<<1|1];
     24     lsum0[rt]=lsum0[rt<<1];
     25     rsum0[rt]=rsum0[rt<<1|1];
     26     if(lsum[rt]==(m-(m>>1)))
     27         lsum[rt]+=lsum[rt<<1|1];
     28     else if(lsum0[rt]==(m-(m>>1)))
     29         lsum0[rt]+=lsum0[rt<<1|1];
     30     if(rsum[rt]==(m>>1))
     31         rsum[rt]+=rsum[rt<<1];
     32     else if(rsum0[rt]==(m>>1))
     33         rsum0[rt]+=rsum0[rt<<1];
     34     msum0[rt]=max(max(msum0[rt<<1],msum0[rt<<1|1]),rsum0[rt<<1]+lsum0[rt<<1|1]);
     35     msum[rt]=max(max(msum[rt<<1],msum[rt<<1|1]),rsum[rt<<1]+lsum[rt<<1|1]);
     36 }
     37 
     38 void FXOR(int rt,int m)
     39 {
     40     if(cover[rt]!=-1)
     41     {
     42         cover[rt]^=1;
     43         sum[rt]=msum[rt]=lsum[rt]=rsum[rt]=m*cover[rt];
     44         msum0[rt]=lsum0[rt]=rsum0[rt]=m*(1-cover[rt]);
     45     }
     46     else
     47     {
     48         XOR[rt]^=1;
     49         sum[rt]=(m-sum[rt]);
     50         int a=lsum[rt],b=rsum[rt];
     51         lsum[rt]=lsum0[rt];
     52         rsum[rt]=rsum0[rt];
     53         lsum0[rt]=a;
     54         rsum0[rt]=b;
     55         a=msum[rt];
     56         msum[rt]=msum0[rt];
     57         msum0[rt]=a;
     58     }
     59 }
     60 
     61 void PushDown(int rt,int m)
     62 {
     63     if(cover[rt]!=-1)
     64     {
     65         lsum[rt<<1]=rsum[rt<<1]=msum[rt<<1]=sum[rt<<1]=(m-(m>>1))*cover[rt];
     66         lsum[rt<<1|1]=rsum[rt<<1|1]=msum[rt<<1|1]=sum[rt<<1|1]=(m>>1)*cover[rt];
     67         lsum0[rt<<1]=rsum0[rt<<1]=msum0[rt<<1]=(m-(m>>1))*(1-cover[rt]);
     68         lsum0[rt<<1|1]=rsum0[rt<<1|1]=msum0[rt<<1|1]=(m>>1)*(1-cover[rt]);
     69         cover[rt<<1]=cover[rt<<1|1]=cover[rt];
     70         XOR[rt<<1]=XOR[rt<<1|1]=0;
     71         cover[rt]=-1;
     72     }
     73     if(XOR[rt])
     74     {
     75         FXOR(rt<<1,(m-(m>>1)));
     76         FXOR(rt<<1|1,(m>>1));
     77         XOR[rt]=0;
     78     }
     79 
     80 }
     81 
     82 void build(int l,int r,int rt)
     83 {
     84     XOR[rt]=0;
     85     if(l==r)
     86     {
     87         scanf("%d",&sum[rt]);
     88         lsum[rt]=rsum[rt]=msum[rt]=cover[rt]=sum[rt];
     89         lsum0[rt]=rsum0[rt]=msum0[rt]=1-sum[rt];
     90         return;
     91     }
     92     int m=(l+r)>>1;
     93     build(lson);
     94     build(rson);
     95     PushUp(rt,r-l+1);
     96 }
     97 
     98 void update(int L,int R,int c,int l,int r,int rt)
     99 {
    100     if(L<=l&&R>=r)
    101     {
    102         if(c==0)
    103             cover[rt]=0,lsum[rt]=rsum[rt]=sum[rt]=msum[rt]=0,lsum0[rt]=rsum0[rt]=msum0[rt]=r-l+1,XOR[rt]=0;
    104         else if(c==1)
    105             cover[rt]=1,lsum[rt]=rsum[rt]=sum[rt]=msum[rt]=r-l+1,lsum0[rt]=rsum0[rt]=msum0[rt]=0,XOR[rt]=0;
    106         else FXOR(rt,r-l+1);
    107         return;
    108     }
    109     int m=(l+r)>>1;
    110     PushDown(rt,r-l+1);
    111     if(L<=m)
    112         update(L,R,c,lson);
    113     if(R>m)
    114         update(L,R,c,rson);
    115     PushUp(rt,r-l+1);
    116 }
    117 
    118 int query1(int L,int R,int l,int r,int rt)
    119 {
    120     if(L<=l&&R>=r)
    121         return sum[rt];
    122     int m=(l+r)>>1;
    123     PushDown(rt,r-l+1);
    124     int res=0;
    125     if(L<=m)
    126         res+=query1(L,R,lson);
    127     if(R>m)
    128         res+=query1(L,R,rson);
    129     return res;
    130 }
    131 
    132 int query2(int L,int R,int l,int r,int rt)
    133 {
    134     if(L<=l&&R>=r)
    135         return msum[rt];
    136     int m=(l+r)>>1;
    137     PushDown(rt,r-l+1);
    138     int ans=0;
    139     if(R<=m)
    140         ans=max(ans,query2(L,R,lson));
    141     else if(L>m)
    142         ans=max(ans,query2(L,R,rson));
    143     else
    144     {
    145         ans=max(ans,query2(L,R,lson));
    146         ans=max(ans,query2(L,R,rson));
    147         int ll,rr;
    148         ll=min(m-L+1,rsum[rt<<1]);
    149         rr=min(R-m,lsum[rt<<1|1]);
    150         ans=max(ans,ll+rr);
    151     }
    152     return ans;
    153 }
    154 
    155 int main(void)
    156 {
    157     int tc,n,m;
    158     int op,a,b,ans;
    159     scanf("%d",&tc);
    160     while(tc--)
    161     {
    162         scanf("%d%d",&n,&m);
    163         build(1,n,1);
    164         while(m--)
    165         {
    166             scanf("%d%d%d",&op,&a,&b);
    167             switch(op)
    168             {
    169             case 0:
    170             case 1:
    171             case 2:
    172                 update(a+1,b+1,op,1,n,1);
    173                 break;
    174             case 3:
    175                 ans=query1(a+1,b+1,1,n,1);
    176                 printf("%d
    ",ans);
    177                 break;
    178             case 4:
    179                 ans=query2(a+1,b+1,1,n,1);
    180                 printf("%d
    ",ans);
    181                 break;
    182             }
    183         }
    184     }
    185     return 0;
    186 }
  • 相关阅读:
    codeforces 1349 A 思维
    codeforces 1358 D 尺区
    codeforces 1251D 二分+贪心
    codeforces 1260 D 二分
    codeforces 1167B 交互ez
    volatile
    计算多级集合/树/部门树的深度
    Java学习路线-知乎
    day06
    day01_虚拟机与主机之间ip配置
  • 原文地址:https://www.cnblogs.com/rootial/p/3255923.html
Copyright © 2011-2022 走看看