您的位置:首页 > 其它

算法模板——splay区间反转 1

2015-01-14 23:05 309 查看
实现的功能:将序列区间反转,并维护

详见BZOJ3223

var
i,j,k,l,m,n,head,a1,a2:longint;
s1:ansistring;
a,b,c,d,fat,lef,rig:array[0..200000] of longint;
procedure swap(var x,y:longint);inline;
var z:longint;
begin
z:=x;x:=y;y:=z;
end;

procedure ext(x:longint);inline;
begin
if (x=0) then exit;
if c[x]=0 then exit;
swap(lef[x],rig[x]);
c[x]:=0;
c[lef[x]]:=1-c[lef[x]];
c[rig[x]]:=1-c[rig[x]];
c[0]:=0;
end;
procedure rt(x:longint);inline;
var f,l:longint;
begin
if x=0 then exit;
ext(x);
if lef[x]=0 then exit;
ext(lef[x]);
f:=x;l:=lef[x];
b[lef[x]]:=b[x];
b[x]:=b[rig[x]]+1+b[rig[l]];
lef[x]:=rig[l];
fat[rig[l]]:=x;
rig[l]:=x;
fat[l]:=fat[x];
fat[x]:=l;
if rig[fat[l]]=x then rig[fat[l]]:=l;
if lef[fat[l]]=x then lef[fat[l]]:=l;
fat[0]:=0;
end;
procedure lt(x:longint);inline;
var f,r:longint;
begin
if x=0 then exit;
ext(x);if rig[x]=0 then exit;
ext(rig[x]);
f:=x;r:=rig[x];
b[rig[x]]:=b[x];
b[x]:=1+b[lef[x]]+b[lef[r]];
rig[x]:=lef[r];
fat[lef[r]]:=x;
lef[r]:=x;
fat[r]:=fat[x];
fat[x]:=r;
if rig[fat[r]]=x then rig[fat[r]]:=r;
if lef[fat[r]]=x then lef[fat[r]]:=r;
fat[0]:=0;
end;
procedure ins(x,y:longint);inline;
begin
if a[y]<a[x] then
begin
if lef[x]=0 then
begin
lef[x]:=y;
fat[y]:=x;
end
else ins(lef[x],y);
end
else
begin
if rig[x]=0 then
begin
rig[x]:=y;
fat[y]:=x;
end
else ins(rig[x],y);
end;
b[x]:=1+b[lef[x]]+b[rig[x]];
end;
procedure up2(var x:longint);inline;
begin
if (fat[x]=0) or (x=0) then exit;
if lef[fat[x]]=x then
begin
if lef[fat[fat[x]]]=fat[x] then
begin
rt(fat[fat[x]]);
rt(fat[x]);
end
else
begin
rt(fat[x]);
lt(fat[x]);
end;
end
else
begin
if rig[fat[fat[x]]]=fat[x] then
begin
lt(fat[fat[x]]);
lt(fat[x]);
end
else
begin
lt(fat[x]);
rt(fat[x]);
end;
end;
end;
procedure up1(x:longint);inline;
begin
if (x=0) or (fat[x]=0) then exit;
if lef[fat[x]]=x then rt(fat[x]) else lt(fat[x]);
end;
procedure splay(x:longint);inline;
begin
if (x=0) or (fat[x]=0) then exit;
while fat[fat[x]]>0 do
up2(x);
if fat[x]>0 then up2(x);
head:=x;
end;
procedure splay2(x:longint);inline;
begin
if (x=0) or (fat[x]=0) then exit;
while fat[fat[fat[x]]]>0 do
up2(x);
if fat[fat[x]]>0 then up1(x);
end;
function getrank(x,y:longint):longint;inline;
begin
if (x=0) then exit(0);
ext(x);
if (b[lef[x]]+1)=y then exit(x);
if (b[lef[x]]+1)>y then exit(getrank(lef[x],y)) else exit(getrank(rig[x],y-1-b[lef[x]]));
end;
procedure turn(x,y:longint);inline;
var a1,a2:longint;
begin
if (x=1) and (y=n) then
c[head]:=1-c[head]
else
begin
if (x=1) then
begin
a1:=getrank(head,y+1);
splay(a1);
ext(a1);
c[lef[a1]]:=1-c[lef[a1]];
end
else
begin
if (y=n) then
begin
a2:=getrank(head,x-1);
splay(a2);
ext(a2);
c[rig[a2]]:=1-c[rig[a2]];
end
else
begin
a1:=getrank(head,x-1);
a2:=getrank(head,y+1);
splay(a2);splay2(a1);
ext(a2);ext(a1);
c[rig[a1]]:=1-c[rig[a1]];
end;
end;
end;
end;
function showoff(x:longint):ansistring;inline;
var s1:ansistring;
begin
if x=0 then exit('');
ext(x);
str(x,s1);
exit(showoff(lef[x])+s1+' '+showoff(rig[x]));
end;
begin
readln(n,m);
for i:=1 to n do
begin
a[i]:=i;c[i]:=0;b[i]:=1;
end;
head:=1;
for i:=2 to n do
begin
ins(head,i);
splay(random(i)+1);
end;
for i:=1 to m do
begin
readln(a1,a2);
turn(a1,a2);
end;
s1:=showoff(head);
writeln(s1);
readln;
end.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: