您的位置:首页 > 其它

【NOI2007】 项链工厂

2012-05-30 22:27 113 查看
解法2:线段树

(*
Problem:    NOI2007 项链工厂
Author:        Chen Yang
Time:        2012.5.29 3:50 pm
State:        Solved
Memo:        线段树、坐标变换
Lesson:        To try
*)
program necklace;
uses math;
const maxn=500100;
maxm=2000000;
type
lt=record
l,r,sum,rc,lc:longint;
lazy:boolean;
end;
var
n,col,i,j,one,fs,q,k,t,k1:longint;
t1,t2:lt;
p:char;
c:array[0..maxn] of longint;
s:array[0..maxm] of lt;
//=======================
procedure maintain(var a,b,c:lt);    inline;
begin
a.sum:=b.sum+c.sum;
if b.rc=c.lc then dec(a.sum);
a.lc:=b.lc; a.rc:=c.rc;
if a.sum=1 then a.lazy:=true else a.lazy:=false;
end;
//=======================
procedure pushlazy(x:longint);       inline;
var
ls,rs:longint;
begin
ls:=x shl 1; rs:=x shl 1+1;
s[ls].lazy:=true;  s[ls].sum:=1;
s[ls].lc:=s[x].lc; s[ls].rc:=s[x].rc;
s[rs].lazy:=true;  s[rs].sum:=1;
s[rs].lc:=s[x].lc; s[rs].rc:=s[x].rc;
end;
//=======================
procedure built(x,l,r:longint);
var
m:longint;
begin
s[x].l:=l; s[x].r:=r;
if l=r then
begin
s[x].lc:=c[l]; s[x].rc:=c[r];
s[x].sum:=1; s[x].lazy:=true;
exit;
end;
s[x].sum:=0; s[x].lazy:=false;
s[x].lc:=0; s[x].rc:=0;
m:=(l+r)>>1;
built(x shl 1,l,m);
built(x shl 1+1,m+1,r);
maintain(s[x],s[x shl 1],s[x shl 1+1]);
end;
//=======================
function find_col(x,p:longint):longint;
var
m:longint;
begin
if (s[x].l<=p)and(p<=s[x].r)and s[x].lazy then exit(s[x].lc);
if s[x].lazy then pushlazy(x);
m:=(s[x].l+s[x].r)>>1;
if p<=m then exit(find_col(x shl 1,p)) else
if p>m then exit(find_col(x shl 1+1,p));
end;
//=======================
function find(x,l,r:longint):lt;
var
m:longint;
t1,t2,t:lt;
begin
if (l<=s[x].l)and(s[x].r<=r)and s[x].lazy then exit(s[x]);
if s[x].lazy then pushlazy(x);
m:=(s[x].l+s[x].r)>>1;
if r<=m then exit(find(x shl 1,l,r)) else
if l>m then exit(find(x shl 1+1,l,r)) else
begin
t1:=find(x shl 1,l,r); t2:=find(x shl 1+1,l,r);
maintain(t,t1,t2);
end;
exit(t);
end;
//=======================
procedure change(x,l,r,c:longint);
var
m:longint;
begin
if (l<=s[x].l)and(s[x].r<=r) then
begin
s[x].lazy:=true; s[x].sum:=1;
s[x].lc:=c; s[x].rc:=c;
exit;
end;
if s[x].lazy then pushlazy(x);
m:=(s[x].l+s[x].r)>>1;
if r<=m then change(x shl 1,l,r,c) else
if l>m then change(x shl 1+1,l,r,c) else
begin
change(x shl 1,l,r,c); change(x shl 1+1,l,r,c);
end;
maintain(s[x],s[x shl 1],s[x shl 1+1]);
end;
//=======================
begin
assign(input,'necklace.in'); reset(input);
assign(output,'necklace.out'); rewrite(output);
read(n,col);
for i:=1 to n do read(c[i]); c[0]:=c
;
built(1,0,n-1);
one:=1; fs:=1;
readln(q);
for i:=1 to q do
begin
read(p);
case p of
'R':begin
readln(k);
one:=(one+n-fs*k) mod n;
end;
'F':begin
fs:=-fs; readln;
end;
'S':begin
readln(j,k); j:=(one+j*fs-fs) mod n; k:=(one+k*fs-fs) mod n;
if j=k then continue;
t:=find_col(1,k); k1:=find_col(1,j);
if t=k1 then continue;
change(1,j,j,t); change(1,k,k,k1);
end;
'P':begin
readln(j,k,t); j:=(one+j*fs-fs) mod n; k:=(one+k*fs-fs) mod n;
if fs=1 then
begin
if k>=j then change(1,j,k,t) else
begin
change(1,j,n-1,t); change(1,0,k,t);
end;
end else
begin
if j>=k then change(1,k,j,t) else
begin
change(1,k,n-1,t); change(1,0,j,t);
end;
end;
end;
'C':begin
read(p);
if p='S' then
begin
readln(j,k); j:=(one+j*fs-fs) mod n; k:=(one+k*fs-fs) mod n; t:=1;
if fs=1 then
begin
if k>=j then t:=find(1,j,k).sum
else begin
t1:=find(1,j,n-1); t2:=find(1,0,k);
t:=t1.sum+t2.sum;
if t1.rc=t2.lc then dec(t);
end;
end else
begin
if j>=k then t:=find(1,k,j).sum
else begin
t1:=find(1,k,n-1); t2:=find(1,0,j);
t:=t1.sum+t2.sum;
if t1.rc=t2.lc then dec(t);
end;
end;
writeln(t);
end else
begin
t:=find(1,0,n-1).sum;
if (t>1)and(s[1].lc=s[1].rc) then dec(t);
writeln(t);
end;
end;
end;
end;
close(input); close(output);
end.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: