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.