BZOJ1858 [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)
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
调试了半天 变量名打错了。。。
维护区间连续的数 类似于维护最大子段和 一下需要10个名字较长的变量把我整乱了。。。
1 #include<cstdio> 2 #include<algorithm> 3 using namespace std; 4 const int N=100000+50; 5 int n,m,a[N]; 6 struct point{int ls,rs,lazy,inv,cnt,sum,lsum,rsum,sum0,lsum0,rsum0;}t[4*N]; 7 inline void print(point i) 8 {printf(" %d %d %d %d %d %d %d %d %d\n\n",i.ls,i.rs,i.cnt,i.sum,i.lsum,i.rsum,i.sum0,i.lsum0,i.rsum0); 9 //printf(" %d %d %d %d %d %d\n\n",i.ls,i.rs,i.cnt,i.sum,i.lsum,i.rsum); 10 } 11 inline void pushup(int i) 12 {t[i].cnt=t[2*i].cnt+t[2*i+1].cnt; 13 14 t[i].lsum=t[2*i].lsum; 15 if(t[2*i].lsum==(t[2*i].rs-t[2*i].ls+1)) t[i].lsum+=t[2*i+1].lsum; 16 t[i].rsum=t[2*i+1].rsum; 17 if(t[2*i+1].rsum==(t[2*i+1].rs-t[2*i+1].ls+1)) t[i].rsum+=t[2*i].rsum; 18 19 t[i].sum=max(t[2*i].rsum+t[2*i+1].lsum 20 ,max(max(t[i].lsum,t[i].rsum) 21 ,max(t[2*i].sum,t[2*i+1].sum))); 22 23 24 t[i].lsum0=t[2*i].lsum0; 25 if(t[2*i].lsum0==t[2*i].rs-t[2*i].ls+1) t[i].lsum0+=t[2*i+1].lsum0; 26 t[i].rsum0=t[2*i+1].rsum0; 27 if(t[2*i+1].rsum0==t[2*i+1].rs-t[2*i+1].ls+1) t[i].rsum0+=t[2*i].rsum0; 28 29 t[i].sum0=max(t[2*i].rsum0+t[2*i+1].lsum0 30 ,max(max(t[i].lsum0,t[i].rsum0) 31 ,max(t[2*i].sum0,t[2*i+1].sum0))); 32 } 33 inline void pass(int i,int x) 34 { 35 t[i].lazy=x; t[i].inv=0; 36 t[i].cnt=t[i].sum=x*(t[i].rs-t[i].ls+1); t[i].sum0=(1-x)*(t[i].rs-t[i].ls+1); 37 if(x==0) {t[i].lsum=t[i].rsum=0; 38 t[i].lsum0=t[i].rsum0=t[i].rs-t[i].ls+1; 39 } 40 else if(x==1) {t[i].lsum0=t[i].rsum0=0; 41 t[i].lsum=t[i].rsum=t[i].rs-t[i].ls+1; 42 } 43 } 44 inline void fan(int i) 45 { if(t[i].lazy!=-1) {pass(i,t[i].lazy^1); return;} 46 t[i].inv^=1; 47 t[i].cnt=t[i].rs-t[i].ls+1-t[i].cnt; 48 swap(t[i].lsum,t[i].lsum0); 49 swap(t[i].rsum,t[i].rsum0); 50 swap(t[i].sum,t[i].sum0); 51 } 52 inline void pushdown(int i) 53 {if(t[i].lazy!=-1) 54 {pass(2*i,t[i].lazy); 55 pass(2*i+1,t[i].lazy); 56 t[i].lazy=-1; 57 } 58 59 if(t[i].inv==1) 60 { t[i].inv=0; 61 fan(2*i); fan(2*i+1); 62 } 63 } 64 void build(int i,int l,int r) 65 {t[i].ls=l; t[i].rs=r; t[i].lazy=-1; 66 if(l==r) {t[i].cnt=t[i].sum=t[i].lsum=t[i].rsum=a[l]; 67 t[i].sum0=t[i].lsum0=t[i].rsum0=1-a[l]; 68 return ; 69 } 70 int mid=t[i].ls+t[i].rs>>1; 71 build(i<<1,l,mid); build(2*i+1,mid+1,r); 72 pushup(i); 73 } 74 void change(int i,int l,int r,int x) 75 {if(l<=t[i].ls && t[i].rs<=r) {pass(i,x); return;} 76 77 pushdown(i); int mid=t[i].ls+t[i].rs>>1; 78 if(l<=mid) change(2*i,l,r,x); 79 if(mid<r) change(2*i+1,l,r,x); 80 pushup(i); 81 } 82 void rev(int i,int l,int r) 83 {if(l<=t[i].ls && t[i].rs<=r) {fan(i); return;} 84 85 pushdown(i); int mid=t[i].ls+t[i].rs>>1; 86 if(l<=mid) rev(2*i,l,r); 87 if(mid<r) rev(2*i+1,l,r); 88 pushup(i); 89 } 90 int ask(int i,int l,int r) 91 {if(l<=t[i].ls && t[i].rs<=r) {return t[i].cnt;} 92 93 pushdown(i); int mid=t[i].ls+t[i].rs>>1; //print(i); 94 if(r<=mid) return ask(2*i,l,r); 95 else if(mid<l)return ask(2*i+1,l,r); 96 else return ask(2*i,l,r)+ask(2*i+1,l,r); 97 } 98 point hehe(int i,int l,int r) 99 {if(l<=t[i].ls && t[i].rs<=r) return t[i]; 100 101 pushdown(i); int mid=t[i].ls+t[i].rs>>1; 102 103 if(r<=mid) return hehe(2*i,l,r); 104 else if(mid<l)return hehe(2*i+1,l,r); 105 else {point r1=hehe(2*i,l,r),r2=hehe(2*i+1,l,r),re; 106 107 re.cnt=r1.cnt+r2.cnt; re.ls=r1.ls; re.rs=r2.rs; 108 109 re.lsum=r1.lsum; 110 if(r1.lsum==r1.rs-r1.ls+1) re.lsum+=r2.lsum; 111 re.rsum=r2.rsum; 112 if(r2.rsum==r2.rs-r2.ls+1) re.rsum+=r1.rsum; 113 114 re.sum=max(r1.rsum+r2.lsum,max(max(re.lsum,re.rsum),max(r1.sum,r2.sum))); 115 return re; 116 } 117 } 118 void shuchu(int i) 119 {if(t[i].ls==t[i].rs) {print(t[i]); return;} 120 121 pushdown(i); print(t[i]); 122 shuchu(2*i); shuchu(2*i+1); 123 } 124 void que(int i) 125 {if(t[i].ls==t[i].rs) {printf("%d ",t[i].cnt);return;} 126 pushdown(i); 127 que(2*i); que(2*i+1); 128 } 129 inline int read() 130 { int k=0,f=1;char ch=getchar(); 131 while(ch<'0'||ch>'9'){if(ch=='-') f=-1; ch=getchar();} 132 while(ch>='0'&&ch<='9')k=k*10+ch-'0',ch=getchar(); 133 return k*f; 134 } 135 int main() 136 { 137 scanf("%d%d",&n,&m); int op,x,y; 138 139 for(int i=1;i<=n;i++) a[i]=read(); 140 build(1,1,n); // shuchu(1); 141 //print(t[1]); 142 143 while(m--) 144 {op=read(); x=read(); y=read(); x++,y++; 145 146 if(op==0) 147 { change(1,x,y,0); //shuchu(1); printf("\n\n\n"); 148 } 149 else if(op==1) 150 { change(1,x,y,1); //shuchu(1); printf("\n\n\n"); 151 } 152 else if(op==2) 153 { rev(1,x,y); //shuchu(1); printf("\n\n\n"); 154 } 155 else if(op==3) 156 { printf("%d\n",ask(1,x,y));// shuchu(1); printf("\n\n\n"); 157 } 158 else if(op==4) 159 { //que(1); printf("\n\n\n"); 160 point ans=hehe(1,x,y); 161 printf("%d\n",ans.sum);// shuchu(1); printf("\n\n\n"); 162 } 163 } 164 return 0; 165 }