1858: [Scoi2010]序列操作

Description

lxhgww最近收到了一个01序列,序列里面包含了n个数,这些数要么是0,要么是1,现在对于这个序列有五种变换操作和询问操作: 0 a b 把[a, b]区间内的所有数全变成0 1 a b 把[a, b]区间内的所有数全变成1 2 a b 把[a,b]区间内的所有数全部取反,也就是说把所有的0变成1,把所有的1变成0 3 a b 询问[a, b]区间内总共有多少个1 4 a b 询问[a, b]区间内最多有多少个连续的1 对于每一种询问操作,lxhgww都需要给出回答,聪明的程序员们,你们能帮助他吗?

Input

输入数据第一行包括2个数,n和m,分别表示序列的长度和操作数目 第二行包括n个数,表示序列的初始状态 接下来m行,每行3个数,op, a, b,(0<=op<=4,0<=a<=b<n)表示对于区间[a, b]执行标号为op的操作="" <="" div="">

Output

对于每一个询问操作,输出一行,包括1个数,表示其对应的答案

Sample Input

10 10
0 0 0 1 1 0 1 0 1 1
1 0 2
3 0 5
2 2 2
4 0 4
0 3 6
2 3 7
4 2 8
1 0 5
0 5 6
3 3 9

Sample Output

5
2
6
5

HINT

对于30%的数据,1<=n, m<=1000
对于100%的数据,1<=n, m<=100000

 
 
线段树维护lx,rx,mx即可,两种标记,如果之前有修改,现在要翻转,那么直接将之前的修改异或即可,
之前有翻转,现在修改,直接修改即可。
  1 #include<iostream>
  2 #include<cstdlib>
  3 #include<cmath>
  4 #include<cstring>
  5 #include<cstdio>
  6 #include<algorithm>
  7 #include<string>
  8 #include<map>
  9 #include<queue>
 10 #include<vector>
 11 #include<set>
 12 #define inf 1000000000
 13 #define maxn 100000+5
 14 #define maxm 10000+5
 15 #define eps 1e-10
 16 #define ll long long
 17 #define for0(i,n) for(int i=0;i<=(n);i++)
 18 #define for1(i,n) for(int i=1;i<=(n);i++)
 19 #define for2(i,x,y) for(int i=(x);i<=(y);i++)
 20 #define for3(i,x,y) for(int i=(x);i>=(y);i--)
 21 #define for4(i,x) for(int i=head[x],y=e[i].go;i;i=e[i].next,y=e[i].go)
 22 using namespace std;
 23 int read(){
 24     int x=0,f=1;char ch=getchar();
 25     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
 26     while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();}
 27     return x*f;
 28 }
 29 struct tree{
 30     int l,r,lx[2],rx[2],mx[2],sum[2],flag;
 31     bool rev;
 32 }f[4*maxn];
 33 int n,m,tmx,trx,a[maxn];
 34 void pushup(int x){
 35     for0(i,1){
 36         f[x].sum[i]=f[x<<1].sum[i]+f[x<<1|1].sum[i];
 37         f[x].lx[i]=f[x<<1].lx[i];
 38         if(f[x<<1].lx[i]==f[x<<1].r-f[x<<1].l+1)
 39             f[x].lx[i]+=f[x<<1|1].lx[i];
 40         f[x].rx[i]=f[x<<1|1].rx[i];
 41         if(f[x<<1|1].rx[i]==f[x<<1|1].r-f[x<<1|1].l+1)
 42             f[x].rx[i]+=f[x<<1].rx[i];
 43         f[x].mx[i]=max(f[x<<1].mx[i],max(f[x<<1|1].mx[i],f[x<<1].rx[i]+f[x<<1|1].lx[i]));
 44     }
 45 }
 46 void update(int x,int c){
 47     f[x].flag=c;
 48     for0(i,1){
 49         f[x].sum[i]=f[x].lx[i]=f[x].rx[i]=f[x].mx[i]=c==i?(f[x].r-f[x].l+1):0;
 50     }
 51 }
 52 void solverever(int x){
 53     f[x].rev^=1;
 54     swap(f[x].sum[0],f[x].sum[1]);
 55     swap(f[x].lx[0],f[x].lx[1]);
 56     swap(f[x].mx[0],f[x].mx[1]);
 57     swap(f[x].rx[0],f[x].rx[1]);
 58     if(f[x].flag!=-1){
 59         f[x].rev=0;
 60         f[x].flag^=1;
 61         return;
 62     }
 63 }
 64 void pushdown(int x){
 65     if(f[x].flag!=-1){
 66         update(x<<1,f[x].flag);update(x<<1|1,f[x].flag);
 67         f[x].flag=-1;f[x].rev=0;
 68     }
 69     if(f[x].rev){
 70         solverever(x<<1);solverever(x<<1|1);
 71         f[x].rev=0;
 72     }
 73 }
 74 void change(int i,int left,int right,int v){
 75     if(f[i].l==left&&f[i].r==right){
 76         update(i,v);
 77         return ;
 78     }
 79     pushdown(i);
 80     int mid=(f[i].l+f[i].r)>>1;
 81     if(right<=mid)change(i<<1,left,right,v);
 82     else if(left>mid)change(i<<1|1,left,right,v);
 83     else change(i<<1,left,mid,v),change(i<<1|1,mid+1,right,v);
 84     pushup(i);
 85 }    
 86 void rever(int i,int left,int right){
 87     if(f[i].l==left&&f[i].r==right){
 88         solverever(i);
 89         return;
 90     }
 91     pushdown(i);
 92     int mid=(f[i].l+f[i].r)>>1;
 93     if(right<=mid)rever(i<<1,left,right);
 94     else if(left>mid)rever(i<<1|1,left,right);
 95     else rever(i<<1,left,mid),rever(i<<1|1,mid+1,right);
 96     pushup(i);
 97 }
 98 int qsum(int i,int left,int right){
 99     if(f[i].l==left&&f[i].r==right)return f[i].sum[1];
100     pushdown(i);
101     int mid=(f[i].l+f[i].r)>>1;
102     if(right<=mid)return qsum(i<<1,left,right);
103     else if(left>mid)return qsum(i<<1|1,left,right);
104     else return qsum(i<<1,left,mid)+qsum(i<<1|1,mid+1,right);
105 }
106 void query(int i,int left,int right){
107     if(f[i].l==left&&f[i].r==right){
108         tmx=max(tmx,max(trx+f[i].lx[1],f[i].mx[1]));
109         if(f[i].sum[1]==f[i].r-f[i].l+1)
110             trx+=f[i].sum[1];
111         else trx=f[i].rx[1];
112         return ;
113     }
114     pushdown(i);
115     int mid=(f[i].l+f[i].r)>>1;
116     if(right<=mid)query(i<<1,left,right);
117     else if(left>mid)query(i<<1|1,left,right);
118     else query(i<<1,left,mid),query(i<<1|1,mid+1,right);
119 }
120 void build(int i,int left,int right){
121     f[i].l=left;f[i].r=right;f[i].flag=-1;f[i].rev=0;
122     if(left==right){
123         for0(j,1)
124             f[i].lx[j]=f[i].mx[j]=f[i].rx[j]=f[i].sum[j]=a[left]==j?1:0;
125         return ;
126     }
127     int mid=(left+right)>>1;
128     build(i<<1,left,mid);build(i<<1|1,mid+1,right);
129     pushup(i);
130 }
131 int main(){
132     //freopen("input.txt","r",stdin);
133     //freopen("output.txt","w",stdout);
134     n=read();m=read();
135     for1(i,n)a[i]=read();
136     build(1,1,n);
137     while(m--){
138         int x=read(),l=read()+1,r=read()+1;
139         if(!x)change(1,l,r,0);
140         else if(x==1)change(1,l,r,1);
141         else if(x==2)rever(1,l,r);
142         else if(x==3)printf("%d\n",qsum(1,l,r));
143         else{
144             trx=tmx=0;
145             query(1,l,r);
146             printf("%d\n",tmx);
147         }
148     }
149     return 0;
150 }
View Code

 

posted @ 2016-07-08 10:42  HTWX  阅读(108)  评论(0编辑  收藏  举报