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<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
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
2
6
5
HINT
对于30%的数据,1<=n, m<=1000
对于100%的数据,1<=n, m<=100000
Source
Day2
看出来简单、写起来有点复杂的线段树,有不少要注意的地方。
表示这是我码过的最长的线段树。
1 program rrr(input,output); 2 type 3 treetype=record 4 l,r,l0,r0,l1,r1,sum,m0,m1,t:longint; 5 end; 6 var 7 a:array[0..400040]of treetype; 8 c:array[0..100010]of longint; 9 n,m,op,x,y,t,i:longint; 10 procedure swap(var a,b:longint); 11 begin 12 t:=a;a:=b;b:=t; 13 end; 14 function min(a,b:longint):longint; 15 begin 16 if a<b then exit(a) else exit(b); 17 end; 18 function max(a,b:longint):longint; 19 begin 20 if a>b then exit(a) else exit(b); 21 end; 22 procedure unite(x,y,k:longint); 23 begin 24 a[k].sum:=a[x].sum+a[y].sum; 25 if a[x].l0=a[x].r-a[x].l+1 then a[k].l0:=a[x].l0+a[y].l0 else a[k].l0:=a[x].l0; 26 if a[y].r0=a[y].r-a[y].l+1 then a[k].r0:=a[x].r0+a[y].r0 else a[k].r0:=a[y].r0; 27 if a[x].l1=a[x].r-a[x].l+1 then a[k].l1:=a[x].l1+a[y].l1 else a[k].l1:=a[x].l1; 28 if a[y].r1=a[y].r-a[y].l+1 then a[k].r1:=a[x].r1+a[y].r1 else a[k].r1:=a[y].r1; 29 if a[x].m0>a[y].m0 then a[k].m0:=a[x].m0 else a[k].m0:=a[y].m0; 30 if a[x].r0+a[y].l0>a[k].m0 then a[k].m0:=a[x].r0+a[y].l0; 31 if a[x].m1>a[y].m1 then a[k].m1:=a[x].m1 else a[k].m1:=a[y].m1; 32 if a[x].r1+a[y].l1>a[k].m1 then a[k].m1:=a[x].r1+a[y].l1; 33 end; 34 procedure build(k,l,r:longint); 35 var 36 mid,i:longint; 37 begin 38 a[k].l:=l;a[k].r:=r;a[k].t:=-1; 39 if l=r then 40 begin 41 if c[l]=0 then begin a[k].l0:=1;a[k].r0:=1;a[k].l1:=0;a[k].r1:=0;a[k].sum:=0;a[k].m0:=1;a[k].m1:=0; end 42 else begin a[k].l0:=0;a[k].r0:=0;a[k].l1:=1;a[k].r1:=1;a[k].sum:=1;a[k].m0:=0;a[k].m1:=1; end; 43 exit; 44 end; 45 mid:=(l+r)>>1;i:=k+k; 46 build(i,l,mid);build(i+1,mid+1,r); 47 unite(i,i+1,k); 48 end; 49 procedure pushdown(k:longint); 50 var 51 x,y:longint; 52 begin 53 if a[k].l=a[k].r then a[k].t:=-1; 54 if a[k].t=-1 then exit; 55 x:=k+k;y:=k+k+1; 56 if a[k].t=1 then 57 begin 58 a[x].sum:=a[x].r-a[x].l+1;a[y].sum:=a[y].r-a[y].l+1; 59 a[x].l0:=0;a[x].r0:=0;a[x].l1:=a[x].sum;a[x].r1:=a[x].sum;a[x].m0:=0;a[x].m1:=a[x].sum; 60 a[y].l0:=0;a[y].r0:=0;a[y].l1:=a[y].sum;a[y].r1:=a[y].sum;a[y].m0:=0;a[y].m1:=a[y].sum; 61 a[x].t:=1;a[y].t:=1; 62 end 63 else if a[k].t=0 then 64 begin 65 a[x].sum:=0;a[y].sum:=0; 66 t:=a[x].r-a[x].l+1;a[x].l0:=t;a[x].r0:=t;a[x].l1:=0;a[x].r1:=0;a[x].m0:=t;a[x].m1:=0; 67 t:=a[y].r-a[y].l+1;a[y].l0:=t;a[y].r0:=t;a[y].l1:=0;a[y].r1:=0;a[y].m0:=t;a[y].m1:=0; 68 a[x].t:=0;a[y].t:=0; 69 end 70 else 71 begin 72 a[x].sum:=a[x].r-a[x].l+1-a[x].sum;a[y].sum:=a[y].r-a[y].l+1-a[y].sum; 73 swap(a[x].l0,a[x].l1);swap(a[x].r0,a[x].r1);swap(a[x].m0,a[x].m1); 74 swap(a[y].l0,a[y].l1);swap(a[y].r0,a[y].r1);swap(a[y].m0,a[y].m1); 75 case a[x].t of 76 0:a[x].t:=1; 77 1:a[x].t:=0; 78 2:a[x].t:=-1; 79 -1:a[x].t:=2; 80 end; 81 case a[y].t of 82 0:a[y].t:=1; 83 1:a[y].t:=0; 84 2:a[y].t:=-1; 85 -1:a[y].t:=2; 86 end; 87 end; 88 a[k].t:=-1; 89 end; 90 procedure change(k:longint); 91 var 92 mid,i:longint; 93 begin 94 pushdown(k); 95 if (x<=a[k].l) and (a[k].r<=y) then 96 begin 97 t:=a[k].r-a[k].l+1; 98 if op=0 then begin a[k].sum:=0;a[k].l0:=t;a[k].r0:=t;a[k].l1:=0;a[k].r1:=0;a[k].m0:=t;a[k].m1:=0;a[k].t:=0; end 99 else begin a[k].sum:=t;a[k].l0:=0;a[k].r0:=0;a[k].l1:=t;a[k].r1:=t;a[k].m0:=0;a[k].m1:=t;a[k].t:=1; end; 100 exit; 101 end; 102 mid:=(a[k].l+a[k].r)>>1;i:=k+k; 103 if x<=mid then change(i); 104 if mid<y then change(i+1); 105 unite(i,i+1,k); 106 end; 107 procedure changef(k:longint); 108 var 109 mid,i:longint; 110 begin 111 pushdown(k); 112 if (x<=a[k].l) and (a[k].r<=y) then 113 begin 114 swap(a[k].l0,a[k].l1);swap(a[k].r0,a[k].r1);swap(a[k].m0,a[k].m1);a[k].sum:=a[k].r-a[k].l+1-a[k].sum;a[k].t:=2; 115 exit; 116 end; 117 mid:=(a[k].l+a[k].r)>>1;i:=k+k; 118 if x<=mid then changef(i); 119 if mid<y then changef(i+1); 120 unite(i,i+1,k); 121 end; 122 function asksum(k:longint):longint; 123 var 124 mid,ans:longint; 125 begin 126 pushdown(k); 127 if (x<=a[k].l) and (a[k].r<=y) then exit(a[k].sum); 128 mid:=(a[k].l+a[k].r)>>1;ans:=0; 129 if x<=mid then ans:=asksum(k+k); 130 if mid<y then ans:=ans+asksum(k+k+1); 131 exit(ans); 132 end; 133 function query(k:longint):longint; 134 var 135 mid,ans,i:longint; 136 begin 137 pushdown(k); 138 if (x<=a[k].l) and (a[k].r<=y) then exit(a[k].m1); 139 mid:=(a[k].l+a[k].r)>>1;ans:=0;i:=k+k; 140 if x<=mid then ans:=query(i); 141 if mid<y then ans:=max(ans,query(i+1)); 142 if (x<=mid) and (mid<y) then ans:=max(ans,min(a[i].r-x+1,a[i].r1)+min(y-a[i+1].l+1,a[i+1].l1)); 143 exit(ans); 144 end; 145 begin 146 assign(input,'r.in');assign(output,'r.out');reset(input);rewrite(output); 147 readln(n,m); 148 for i:=1 to n do read(c[i]); 149 build(1,1,n); 150 for i:=1 to m do 151 begin 152 readln(op,x,y);inc(x);inc(y); 153 if (op=0) or (op=1) then change(1) 154 else if op=2 then changef(1) 155 else if op=3 then writeln(asksum(1)) 156 else writeln(query(1)); 157 end; 158 close(input);close(output); 159 end.