bzoj1858
来源:互联网 发布:易语言软件下载 编辑:程序博客网 时间:2024/04/30 04:19
1858: [Scoi2010]序列操作
Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 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<=bOutput
对于每一个询问操作,输出一行,包括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
线段树的应用
好久不写普通线段树了,写了竟然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.
- bzoj1858
- bzoj1858
- bzoj1858【scoi2010】序列操作
- [BZOJ1858] [Scoi2010]序列操作
- bzoj1858: [Scoi2010]序列操作
- BZOJ1858 [Scoi2010]序列操作
- BZOJ1858: [Scoi2010]序列操作
- BZOJ1858 [Scoi2010]序列操作
- bzoj1858: [Scoi2010]序列操作
- bzoj1858 [Scoi2010]序列操作
- bzoj1858序列操作 线段树
- 【BZOJ1858】[Scoi2010]序列操作 线段树
- [BZOJ1858]SCOI2010序列操作|线段树
- bzoj1858 序列操作 线段树打标记
- 【codevs2421】【BZOJ1858】序列操作,线段树
- 【BZOJ1858】[Scoi2010]序列操作【线段树】
- BZOJ1858 序列操作 (线段树)
- 【BZOJ1858】序列操作(SCOI2010)-线段树
- CSS写省略号
- DDS程序
- 【C/C++和指针】auto_ptr智能指针
- 兼容EXT3的UploadDialog
- 横表与纵表的区分
- bzoj1858
- proteus元件表
- 黑马程序员_基础回顾之多线程
- 如何走好后面的路?
- 图--邻接表(建立、深搜、广搜)
- 夏季哪些蔬菜不适合生吃凉拌,食用会发生危险
- 一个暴风雨的夜晚——一个普通而又伟大老师的一天
- Wordpress主题制作不完全指南
- 关系型数据库性能优化总结