您的位置:首页 > 其它

NOI 项链工厂

2012-07-17 15:30 211 查看
原题:NOI 项链工厂

方法:线断树

program necklace;
const
maxn=500000;
var
ls,rs,s,cl,cr,z:array[1..maxn shl 2]of longint; sto,col,cur:longint; rev:boolean;
procedure update(const x:longint);
begin
cl[x]:=cl[ls[x]]; cr[x]:=cr[rs[x]];
s[x]:=s[ls[x]]+s[rs[x]]-ord(cr[ls[x]]=cl[rs[x]]);
end;
procedure build(var x:longint;const l,r:longint);
var mid:longint;
begin
inc(sto); x:=sto; mid:=(l+r)>>1;
if l=r then begin read(cl[x]); cr[x]:=cl[x]; s[x]:=1; exit; end;
build(ls[x],l,mid);	build(rs[x],mid+1,r); update(x);
end;
procedure put(const x,cc:longint);
begin
cl[x]:=cc; cr[x]:=cc; z[x]:=cc; s[x]:=1;
end;
procedure modify(const x,cc:longint);
begin
if cc=0 then exit;
if ls[x]<>0 then put(ls[x],cc);
if rs[x]<>0 then put(rs[x],cc); z[x]:=0;
end;
function get_c(const x,l,r,k:longint):longint;
var mid:longint;
begin
if z[x]<>0 then exit(z[x]); mid:=(l+r)>>1;
if k=l then exit(cl[x]);	if k=r then exit(cr[x]);
if k<=mid then exit(get_c(ls[x],l,mid,k));
exit(get_c(rs[x],mid+1,r,k));
end;
function get(const x,l,r,ll,rr:longint):longint;
var mid:longint;
begin
modify(x,z[x]); mid:=(l+r)>>1;
if (ll=l)and(rr=r) then exit(s[x]);
if rr<=mid then exit(get(ls[x],l,mid,ll,rr)) else
if ll>mid then exit(get(rs[x],mid+1,r,ll,rr)) else
get:=get(ls[x],l,mid,ll,mid)+get(rs[x],mid+1,r,mid+1,rr)-ord(cr[ls[x]]=cl[rs[x]]);
end;
procedure change(const x,l,r,k:longint);
var mid:longint;
begin
modify(x,z[x]);mid:=(l+r)>>1;
if (l=r) then begin cl[x]:=col; cr[x]:=col; exit; end;
if k<=mid then change(ls[x],l,mid,k) else change(rs[x],mid+1,r,k);
update(x);
end;
procedure change(const x,l,r,ll,rr:longint);
var mid:longint;
begin
modify(x,z[x]);mid:=(l+r)>>1;
if (l=ll)and(r=rr) then begin put(x,col); exit; end;
if rr<=mid then change(ls[x],l,mid,ll,rr) else
if ll>mid then change(rs[x],mid+1,r,ll,rr) else begin
change(ls[x],l,mid,ll,mid);change(rs[x],mid+1,r,mid+1,rr);
end;update(x);
end;
var n,m,x,y,i,j:longint;ch:char; tmp_tot:integer;
function g(const x:longint):longint;
begin
g:=cur; if not rev then inc(g,x-1) else inc(g,n-x+1);
if g>n then dec(g,n);
end;
Begin
assign(input,'input.txt');reset(input);assign(output,'output.txt');rewrite(output);
readln(n,m); build(x,1,n); readln(m); rev:=false;cur:=1;
for m:=1 to m do begin
repeat read(ch); until ch in ['R','F','P','C','S'];
if ch='C' then begin
if eoln then writeln(s[1]-ord(cl[1]=cr[1])+ord(s[1]=1)) else begin
read(ch);read(i,j);i:=g(i);j:=g(j);
if (not rev)then if (i<=j) then writeln(get(1,1,n,i,j)) else
writeln(get(1,1,n,1,j)+get(1,1,n,i,n)-ord(cl[1]=cr[1])) else
if (j<=i) then writeln(get(1,1,n,j,i)) else
writeln(get(1,1,n,1,i)+get(1,1,n,j,n)-ord(cl[1]=cr[1]));
end; end else if ch='R' then begin read(x);
if rev then inc(cur,x) else inc(cur,n-x); if cur>n then dec(cur,n);
end else if ch='F' then rev:=not rev
else if ch='S' then begin
readln(i,j);i:=g(i);j:=g(j);
x:=get_c(1,1,n,i);y:=get_c(1,1,n,j);
if x=y then continue;
col:=y;change(1,1,n,i);col:=x;change(1,1,n,j);
end else if ch='P' then begin
read(i,j,col);i:=g(i);j:=g(j);
if (not rev)then if(i<=j) then change(1,1,n,i,j) else begin
change(1,1,n,1,j);change(1,1,n,i,n);end else
if (j<=i) then change(1,1,n,j,i) else begin
change(1,1,n,1,i);change(1,1,n,j,n);end;
end;
end;
close(input);close(output);
end.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: