bzoj1858

来源:互联网 发布:易语言软件下载 编辑:程序博客网 时间:2024/04/30 04:19

1858: [Scoi2010]序列操作

Time Limit: 10 Sec  Memory Limit: 64 MB
Submit: 444  Solved: 240
[Submit][Status][Discuss]

Description

lxhgww最近收到了一个01序列,序列里面包含了n个数,这些数要么是0,要么是1,现在对于这个序列有五种变换操作和询问操作:0 a b 把[a, b]区间内的所有数全变成01 a b 把[a, b]区间内的所有数全变成12 a b 把[a,b]区间内的所有数全部取反,也就是说把所有的0变成1,把所有的1变成03 a b 询问[a, b]区间内总共有多少个14 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

HINT

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




线段树的应用

好久不写普通线段树了,写了竟然wa了……


program bzoj1858;type    group=record                max,maxl,maxr:longint;    end;var   a,b,o,tot,n,m,i,j,k:longint;   stop,sum,left,right,maxl1,maxr1,max1,maxl0,maxr0,max0:array [0..200001] of longint;procedure swap (var a,b:longint);inline;begin     if a=b then exit;     a:=a xor b;     b:=a xor b;     a:=a xor b;end;function max (a,b:longint):longint;inline;begin     if a>b then exit(a) else exit(b);end;procedure build (s,e,now:longint);var   mid:longint;begin     stop[now]:=-1;     maxl0[now]:=e-s+1;     maxr0[now]:=e-s+1;     max0[now]:=e-s+1;     if s=e then exit;     mid:=(s+e) div 2;     inc(tot);     left[now]:=tot;     build(s,mid,tot);     inc(tot);     right[now]:=tot;     build(mid+1,e,tot);end;procedure quick (o,l,r,now:longint);begin     case o of          0:          begin               sum[now]:=0;               maxl0[now]:=r-l+1;               maxr0[now]:=r-l+1;               max0[now]:=r-l+1;               maxl1[now]:=0;               maxr1[now]:=0;               max1[now]:=0;               stop[now]:=0;          end;          1:          begin               sum[now]:=r-l+1;               maxl0[now]:=0;               maxr0[now]:=0;               max0[now]:=0;               maxl1[now]:=r-l+1;               maxr1[now]:=r-l+1;               max1[now]:=r-l+1;               stop[now]:=1;          end;          2:          begin               sum[now]:=r-l+1-sum[now];               swap(maxl0[now],maxl1[now]);               swap(maxr0[now],maxr1[now]);               swap(max0[now],max1[now]);               case stop[now] of                    -1:stop[now]:=2;                    0:stop[now]:=1;                    1:stop[now]:=0;                    2:stop[now]:=-1;               end;          end;     end;end;procedure update (l,r,now:longint);var   mid:longint;begin     if stop[now]=-1 then exit;     mid:=(l+r) div 2;     quick(stop[now],l,mid,left[now]);     quick(stop[now],mid+1,r,right[now]);     stop[now]:=-1;end;procedure fill (o,s,e,l,r,now:longint);var   mid:longint;begin     if (s=l)and(e=r) then        begin             quick(o,l,r,now);             exit;        end;     update(l,r,now);     mid:=(l+r) div 2;     if e<=mid then fill(o,s,e,l,mid,left[now])               else     if s>mid then fill(o,s,e,mid+1,r,right[now])              else              begin                   fill(o,s,mid,l,mid,left[now]);                   fill(o,mid+1,e,mid+1,r,right[now]);              end;     sum[now]:=sum[left[now]]+sum[right[now]];     if maxl0[left[now]]=mid-l+1 then maxl0[now]:=maxl0[left[now]]+maxl0[right[now]]                                 else maxl0[now]:=maxl0[left[now]];     if maxr0[right[now]]=r-mid then maxr0[now]:=maxr0[right[now]]+maxr0[left[now]]                                else maxr0[now]:=maxr0[right[now]];     max0[now]:=max0[left[now]];     if max0[now]<max0[right[now]] then max0[now]:=max0[right[now]];     if max0[now]<maxr0[left[now]]+maxl0[right[now]] then max0[now]:=maxr0[left[now]]+maxl0[right[now]];     if maxl1[left[now]]=mid-l+1 then maxl1[now]:=maxl1[left[now]]+maxl1[right[now]]                                 else maxl1[now]:=maxl1[left[now]];     if maxr1[right[now]]=r-mid then maxr1[now]:=maxr1[right[now]]+maxr1[left[now]]                                else maxr1[now]:=maxr1[right[now]];     max1[now]:=max1[left[now]];     if max1[now]<max1[right[now]] then max1[now]:=max1[right[now]];     if max1[now]<maxr1[left[now]]+maxl1[right[now]] then max1[now]:=maxr1[left[now]]+maxl1[right[now]];end;function qsum (s,e,l,r,now:longint):longint;var   mid:longint;begin     if (s=l)and(e=r) then exit(sum[now]);     update(l,r,now);     mid:=(l+r) div 2;     if e<=mid then exit(qsum(s,e,l,mid,left[now]))               else     if s>mid then exit(qsum(s,e,mid+1,r,right[now]))              else exit(qsum(s,mid,l,mid,left[now])+qsum(mid+1,e,mid+1,r,right[now]));end;function find (s,e,l,r,now:longint):group;var   mid:longint;   ans,q,p:group;begin     if (s=l)and(e=r) then        begin             ans.max:=max1[now];             ans.maxl:=maxl1[now];             ans.maxr:=maxr1[now];             exit(ans);        end;     update(l,r,now);     mid:=(l+r) div 2;     if e<=mid then exit(find(s,e,l,mid,left[now]))               else     if s>mid then exit(find(s,e,mid+1,r,right[now]))              else     begin          q:=find(s,mid,l,mid,left[now]);          p:=find(mid+1,e,mid+1,r,right[now]);          ans.max:=max(max(q.max,p.max),q.maxr+p.maxl);          if q.maxl=mid-s+1 then ans.maxl:=q.maxl+p.maxl                            else ans.maxl:=q.maxl;          if p.maxr=e-mid then ans.maxr:=p.maxr+q.maxr                          else ans.maxr:=p.maxr;          exit(ans);     end;end;begin                         read(n,m);     build(1,n,0);     for i:=1 to n do         begin              read(k);              fill(k,i,i,1,n,0);         end;     for i:=1 to m do         begin              read(o,a,b);              inc(a);              inc(b);              case o of                   0:fill(0,a,b,1,n,0);                   1:fill(1,a,b,1,n,0);                   2:fill(2,a,b,1,n,0);                   3:writeln(qsum(a,b,1,n,0));                   4:writeln(find(a,b,1,n,0).max);              end;         end;end.


原创粉丝点击