[BZOJ1858] [Scoi2010]序列操作

来源:互联网 发布:周杰伦婚礼音乐 知乎 编辑:程序博客网 时间:2024/05/16 16:05

传送门

http://www.lydsy.com/JudgeOnline/problem.php?id=1858

题目大意

给定一个01序列每次操作
0:[L,R]都变0
1:[L,R]都变1
2:[L,R]0变1,1变0
3:查询[L,R]区间内1个数
4:查询[L,R]区间内最长连续1个数

题解

明显线段树
维护
1.区间和
2.左端点开始连续0个数
3.右端点开始连续0个数
4.最长连续0个数
5.左端点开始连续1个数
6.右端点开始连续1个数
7.最长连续1个数
注意细节细节细节细节细节细节细节细节细节细节细节细节细节细节

const maxn=100005;type group=record  maxx,maxl,maxr:longint; end;var w:array[0..8*maxn,1..10]of longint; i,j,k:longint; a,b,c:longint; n,m:longint;procedure swap(var a,b:longint);var c:longint;begin c:=a; a:=b; b:=c;end;function max(a,b:longint):longint;begin if a>b then exit(a) else exit(b);end;procedure pushup(a:longint);begin w[a,3]:=w[a<<1,3]+w[a<<1+1,3]; w[a,4]:=w[a<<1,4]; if w[a<<1,4]=w[a<<1,2]-w[a<<1,1]+1 then inc(w[a,4],w[a<<1+1,4]); w[a,5]:=w[a<<1+1,5]; if w[a<<1+1,5]=w[a<<1+1,2]-w[a<<1+1,1]+1 then inc(w[a,5],w[a<<1,5]); w[a,6]:=max(max(w[a<<1,6],w[a<<1+1,6]),w[a<<1,5]+w[a<<1+1,4]); w[a,7]:=w[a<<1,7]; if w[a<<1,7]=w[a<<1,2]-w[a<<1,1]+1 then inc(w[a,7],w[a<<1+1,7]); w[a,8]:=w[a<<1+1,8]; if w[a<<1+1,8]=w[a<<1+1,2]-w[a<<1+1,1]+1 then inc(w[a,8],w[a<<1,8]); w[a,9]:=max(max(w[a<<1,9],w[a<<1+1,9]),w[a<<1,8]+w[a<<1+1,7]);end;procedure pushdown(a:longint);var b,i:longint;begin if w[a,1]=w[a,2] then begin w[a,10]:=-1; exit; end; b:=a<<1; if w[a,10]=0 then begin  w[b,10]:=0; w[b,3]:=0; w[b,7]:=0; w[b,8]:=0; w[b,9]:=0; w[b,4]:=w[b,2]-w[b,1]+1; w[b,5]:=w[b,4]; w[b,6]:=w[b,4]; inc(b);  w[b,10]:=0; w[b,3]:=0; w[b,7]:=0; w[b,8]:=0; w[b,9]:=0; w[b,4]:=w[b,2]-w[b,1]+1; w[b,5]:=w[b,4]; w[b,6]:=w[b,4]; end; if w[a,10]=1 then begin  w[b,10]:=1; w[b,3]:=w[b,2]-w[b,1]+1; w[b,4]:=0; w[b,5]:=0; w[b,6]:=0; w[b,7]:=w[b,3]; w[b,8]:=w[b,3]; w[b,9]:=w[b,3]; inc(b);  w[b,10]:=1; w[b,3]:=w[b,2]-w[b,1]+1; w[b,4]:=0; w[b,5]:=0; w[b,6]:=0; w[b,7]:=w[b,3]; w[b,8]:=w[b,3]; w[b,9]:=w[b,3]; end; if w[a,10]=2 then begin  if w[b,10]=0 then w[b,10]:=1 else if w[b,10]=1 then w[b,10]:=0 else if w[b,10]=2 then w[b,10]:=-1 else if w[b,10]=-1 then w[b,10]:=2;  w[b,3]:=w[b,2]-w[b,1]+1-w[b,3]; for i:=4 to 6 do swap(w[b,i],w[b,i+3]); inc(b);  if w[b,10]=0 then w[b,10]:=1 else if w[b,10]=1 then w[b,10]:=0 else if w[b,10]=2 then w[b,10]:=-1 else if w[b,10]=-1 then w[b,10]:=2;  w[b,3]:=w[b,2]-w[b,1]+1-w[b,3]; for i:=4 to 6 do swap(w[b,i],w[b,i+3]); end; w[a,10]:=-1;end;procedure build(a,l,r:longint);var mid:longint;begin w[a,1]:=l; w[a,2]:=r; w[a,10]:=-1; for i:=3 to 9 do w[a,i]:=0; if l=r then begin  read(w[a,3]);  if w[a,3]=0  then for i:=4 to 6 do w[a,i]:=1  else for i:=7 to 9 do w[a,i]:=1;  exit; end; mid:=(l+r)>>1; build(a<<1,l,mid); build(a<<1+1,mid+1,r); pushup(a);end;procedure update(a,l,r,c:longint);var mid,b,i:longint;begin if w[a,10]<>-1 then pushdown(a); if (l=w[a,1])and(r=w[a,2]) then begin  w[a,10]:=c; b:=a;  case c of  0:begin w[b,10]:=0; w[b,3]:=0; w[b,7]:=0; w[b,8]:=0; w[b,9]:=0; w[b,4]:=w[b,2]-w[b,1]+1; w[b,5]:=w[b,4]; w[b,6]:=w[b,4]; end;  1:begin w[b,10]:=1; w[b,3]:=w[b,2]-w[b,1]+1; w[b,4]:=0; w[b,5]:=0; w[b,6]:=0; w[b,7]:=w[b,3]; w[b,8]:=w[b,3]; w[b,9]:=w[b,3]; end;  2:begin w[b,10]:=2; w[b,3]:=w[b,2]-w[b,1]+1-w[b,3]; for i:=4 to 6 do swap(w[b,i],w[b,i+3]); end;  end;  exit; end; mid:=(w[a,1]+w[a,2])>>1; if r<=mid then update(a<<1,l,r,c) else if l>mid then update(a<<1+1,l,r,c) else begin update(a<<1,l,mid,c); update(a<<1+1,mid+1,r,c); end; pushup(a);end;function query1(a,l,r:longint):longint;var mid:longint;begin if w[a,10]<>-1 then pushdown(a); if (l=w[a,1])and(w[a,2]=r) then exit(w[a,3]); mid:=(w[a,1]+w[a,2])>>1; if r<=mid then exit(query1(a<<1,l,r)) else if l>mid then exit(query1(a<<1+1,l,r)) else exit(query1(a<<1,l,mid)+query1(a<<1+1,mid+1,r));end;function query2(a,l,r:longint):group;var mid:longint; ans,p,q:group;begin if w[a,10]<>-1 then pushdown(a); if (l=w[a,1])and(w[a,2]=r) then begin  ans.maxx:=w[a,9]; ans.maxl:=w[a,7]; ans.maxr:=w[a,8];  exit(ans); end; mid:=(w[a,1]+w[a,2])>>1; if r<=mid then exit(query2(a<<1,l,r)) else if l>mid then exit(query2(a<<1+1,l,r)) else begin  p:=query2(a<<1,l,mid); q:=query2(a<<1+1,mid+1,r);  ans.maxx:=max(max(p.maxx,q.maxx),p.maxr+q.maxl);  ans.maxl:=p.maxl; if p.maxl=mid-l+1 then inc(ans.maxl,q.maxl);  ans.maxr:=q.maxr; if q.maxr=r-mid then inc(ans.maxr,p.maxr);  exit(ans); end;end;begin assign(input,'operation.in'); assign(output,'operation.out'); reset(input); rewrite(output); readln(n,m); build(1,1,n); for i:=1 to m do  begin   readln(a,b,c); inc(b); inc(c);   if a<=2   then update(1,b,c,a)   else if a=3 then writeln(query1(1,b,c))               else writeln(query2(1,b,c).maxx);  end; close(input); close(output);end.
0 0
原创粉丝点击