您的位置:首页 > 其它

BZOJ1858: [Scoi2010]序列操作

2014-08-10 12:35 363 查看

1858: [Scoi2010]序列操作

Time Limit: 10 Sec Memory Limit: 64 MB
Submit: 1068 Solved: 545
[Submit][Status]

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

Sample Output

5
2
6
5

HINT

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

Source

Day2

这题的区间合并实在太恶心了,写完我都快吐了。。。那天过来再调吧。。。

代码:

{$inline on}
{$M 1000000000,0,maxlongint}
const maxn=100000+1000;
var s,sum1,sum0,v,lx0,rx0,lx1,rx1,mx0,mx1,fa,id,a:array[0..maxn] of longint;
rev,tag:array[0..maxn] of boolean;
c:array[0..maxn,0..1] of longint;
i,n,m,x,y,z,rt,ch,ll,rr:longint;
procedure swap(var x,y:longint);inline;
var t:longint;
begin
t:=x;x:=y;y:=t;
end;
function max(x,y:longint):longint;inline;
begin
if x>y then exit(x) else exit(y);
end;
procedure pushup(x:longint);
var l,r:longint;
begin
l:=c[x,0];r:=c[x,1];
s[x]:=s[l]+s[r]+1;
sum1[x]:=sum1[l]+sum1[r]+ord(v[x]=1);
sum0[x]:=sum0[l]+sum0[r]+ord(v[x]=0);
if lx0[l]=s[l] then
begin
if v[x]=0 then lx0[x]:=s[l]+1+lx0[r]
else lx0[x]:=s[l];
end
else lx0[x]:=lx0[l];
if rx0[r]=s[r] then
begin
if v[x]=0 then rx0[x]:=s[r]+1+rx0[l]
else rx0[x]:=s[r];
end;
if lx1[l]=s[l] then
begin
if v[x]=1 then lx1[x]:=s[l]+1+lx1[r]
else lx1[x]:=s[l];
end
else lx1[x]:=lx1[l];
if rx1[r]=s[r] then
begin
if v[x]=1 then rx1[x]:=s[r]+1+rx1[l]
else rx1[x]:=s[r];
end;
mx0[x]:=max(mx0[l],mx0[r]);
if v[x]=0 then mx0[x]:=max(mx0[x],rx0[l]+lx0[r]+1);
mx1[x]:=max(mx1[l],mx1[r]);
if v[x]=1 then mx1[x]:=max(mx1[x],rx1[l]+lx1[r]+1);
end;
procedure rotate(x:longint;var k:longint);
var y,z,l,r:longint;
begin
y:=fa[x];z:=fa[y];
l:=ord(c[y,1]=x);r:=l xor 1;
if y=k then k:=x else c[z,ord(c[z,1]=y)]:=x;
fa[x]:=z;fa[y]:=x;fa[c[x,r]]:=y;
c[y,l]:=c[x,r];c[x,r]:=y;
pushup(y);pushup(x);
end;
procedure splay(x:longint;var k:longint);
var y,z:longint;
begin
while x<>k do
begin
y:=fa[x];z:=fa[y];
if y<>k then
if (c[z,0]=y) xor (c[y,0]=x) then rotate(x,k)
else rotate(y,k);
rotate(x,k);
end;
end;

procedure build(l,r,f:longint);
var mid,x,y:longint;
begin
if l>r then exit;
mid:=(l+r)>>1;
x:=id[mid];y:=id[f];
c[y,ord(mid>f)]:=x;fa[x]:=y;
v[x]:=a[mid];
if l=r then
begin
s[x]:=1;sum0[x]:=ord(v[x]=0);sum1[x]:=ord(v[x]=1);
lx0:=sum0;rx0:=sum0;mx0:=sum0;
lx1:=sum1;rx1:=sum1;mx1:=sum1;
exit;
end;
build(l,mid-1,mid);build(mid+1,r,mid);
pushup(x);
end;
procedure init;
begin
readln(n,m);
a[1]:=-1;a[n+2]:=-1;
for i:=2 to n+1 do read(a[i]);readln;
for i:=1 to n+2 do id[i]:=i;
build(1,n+2,0);rt:=(n+3)>>1;
end;
procedure same0(x:longint);
begin
tag[x]:=true;v[x]:=0;
sum0[x]:=s[x];lx0[x]:=s[x];rx0[x]:=s[x];mx0[x]:=s[x];
sum1[x]:=0;lx1[x]:=0;rx1[x]:=0;mx1[x]:=0;
end;
procedure same1(x:longint);
begin
tag[x]:=true;v[x]:=1;
sum1[x]:=s[x];lx1[x]:=s[x];rx1[x]:=s[x];mx1[x]:=s[x];
sum0[x]:=0;lx0[x]:=0;rx0[x]:=0;mx0[x]:=0;
end;
procedure rever(x:longint);
begin
if (x=0) or (tag[x]) then exit;
rev[x]:=not(rev[x]);v[x]:=v[x] xor 1;
swap(lx0[x],lx1[x]);
swap(rx0[x],rx1[x]);
swap(sum0[x],sum1[x]);
swap(mx0[x],mx1[x]);
end;
procedure pushdown(x:longint);
var l,r:longint;
begin
l:=c[x,0];r:=c[x,1];
if tag[x] then
begin
tag[x]:=false;rev[x]:=false;
if v[x]=0 then begin same0(l);same0(r);end
else begin same1(l);same1(r);end;
end;
if rev[x] then
begin
rev[x]:=false;
rever(l);rever(r);
pushup(x);
end;
end;

function find(x,rk:longint):longint;
var l,r:longint;
begin
pushdown(x);l:=c[x,0];r:=c[x,1];
if s[l]+1=rk then exit(x)
else if s[l]>=rk then exit(find(l,rk))
else exit(find(r,rk-s[l]-1));
end;

procedure split(l,r:longint;var x,y:longint);
begin
x:=find(rt,l);y:=find(rt,r);
splay(x,rt);splay(y,c[x,1]);
end;
procedure main;
begin
for i:=1 to  m do
begin
readln(ch,ll,rr);inc(ch);inc(ll,1);inc(rr,3);
split(ll,rr,x,y);
case ch of
1:same0(c[y,0]);
2:same1(c[y,0]);
3:rever(c[y,0]);
4:writeln(sum1[c[y,0]]);
5:writeln(mx1[c[y,0]]);
end;
end;
end;
begin
assign(input,'input.txt');assign(output,'output.txt');
reset(input);rewrite(output);
init;
main;
close(input);close(output);
end.


View Code
UPD:这是一份错的代码。。。

正解戳这里额:/article/6822595.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: