NOI 项链工厂

原题: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.


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值