[BZOJ3223] Tyvj 1729 文藝平衡樹
阿新 • • 發佈:2019-02-11
傳送門
題目大意
[1,n],每次翻轉[L,R],輸出最後的序列
題解
Splay模板題
翻轉標記下放注意的細節在code裡
Splay第一題~~
const
maxn=100005;
var
w:array[-1..maxn,1..6]of longint; //1:左兒子 2:右兒子 3:父 4:子樹節點數 5:權值 6:翻轉標記
i,j,k:longint;
n,m,l,r,root,sum:longint;
procedure swap(var a,b:longint);
var c:longint;
begin c:=a; a:=b; b:=c; end;
procedure pushdown(a:longint);
begin
w[a,6]:=-1;
swap(w[a,1],w[a,2]);
if w[w[a,1],6]=1 then w[w[a,1],6]:=-1 else w[w[a,1],6]:=1;
if w[w[a,2],6]=1 then w[w[a,2],6]:=-1 else w[w[a,2],6]:=1;
end;
procedure rotate(a,kind:longint); //右旋:1左旋:2
var unkind:longint;
begin
unkind:=kind xor 3; //因為向下尋找的時候就把從root到那個點的路徑上的標記都下放了,所以不用再下放
w[a,4]:=w[w[a,3],4];
w[w[a,3],4]:=w[w[a,unkind],4]+w[w[w[a,3],unkind],4]+1;
w[w[a,3],kind]:=w[a,unkind];
w[w[a,unkind],3]:=w[a,3];
w[a,unkind]:=w[a,3];
w[a,3]:=w[w[a,3],3];
w[w[a,unkind],3]:=a;
if w[a,3]<>-1 then
if w[w[a,3],2]=w[a,unkind]
then w[w[a,3],2]:=a
else w[w[a,3],1]:=a;
end ;
procedure splay(a,goal:longint);
var kind,unkind:longint;
begin
while w[a,3]<>goal do
begin
if w[w[a,3],1]=a then kind:=1 else kind:=2;
unkind:=kind xor 3;
if w[a,6]=1 then pushdown(a);
if w[w[a,3],3]=goal then rotate(a,kind)
else
if w[w[w[a,3],3],kind]=w[a,3]
then begin rotate(w[a,3],kind); rotate(a,kind); end
else begin rotate(a,kind); rotate(a,unkind); end;
end;
if goal=-1 then root:=a;
end;
procedure init(a:longint);
var tt,fa,kind:longint;
begin
tt:=root;
while tt<>-1 do
begin
fa:=tt;
if a<w[tt,5]
then begin tt:=w[tt,1]; kind:=1; end
else begin tt:=w[tt,2]; kind:=2; end;
end;
inc(sum); w[sum,1]:=-1; w[sum,2]:=-1; w[sum,3]:=fa; w[sum,4]:=1; w[sum,5]:=a; w[sum,6]:=-1; w[fa,kind]:=sum; inc(w[fa,4]);
splay(sum,-1);
end;
function find(rank:longint):longint; //rank表示它前面有rank個它是第rank+1個
var tt:longint;
begin
tt:=root; if w[tt,6]=1 then pushdown(tt); //向下尋找時要先下方標記,防止下放了,while的條件就滿足了的情況
while w[w[tt,1],4]<>rank do
begin
if w[w[tt,1],4]<rank
then begin dec(rank,w[w[tt,1],4]+1); tt:=w[tt,2]; end
else tt:=w[tt,1];
if w[tt,6]=1 then pushdown(tt);
end;
exit(tt);
end;
procedure print(a:longint);
begin
if w[a,6]=1 then pushdown(a);
if w[a,1]<>-1 then print(w[a,1]);
if (w[a,5]<>0)and(w[a,5]<>n+1) then write(w[a,5],' ');
if w[a,2]<>-1 then print(w[a,2]);
if (a=root) then writeln;
end;
begin
readln(n,m);
sum:=1; root:=1; w[1,1]:=-1; w[1,2]:=-1; w[1,3]:=-1; w[1,4]:=1; w[1,5]:=0; w[1,6]:=-1;
for i:=1 to n+1 do
init(i);
for i:=1 to m do
begin
readln(l,r);
splay(find(l-1),-1);
splay(find(r+1),root);
if w[w[w[root,2],1],6]=-1 then w[w[w[root,2],1],6]:=1 else w[w[w[root,2],1],6]:=-1;
end;
print(root);
end.