文藝平衡樹
fromadmin
背景 background
此為平衡樹系列第二道:文藝平衡樹
描述 description
您需要寫一種資料結構(可參考題目標題),來維護乙個有序數列,其中需要提供以下操作:
翻轉乙個區間,例如原有序序列是5 4 3 2 1,翻轉區間是[2,4]的話,結果是5 2 3 4 1
輸入格式 inputformat
第一行為n,m n表示初始序列有n個數,這個序列依次是(1,2……n-1,n) m表示翻轉操作次數
接下來m行每行兩個數[l,r] 資料保證 1<=l<=r<=n
輸出格式 outputformat
輸出一行n個數字,表示原始序列經過m次變換後的結果
樣例輸入 sampleinput [複製資料]
5 31 3
1 31 4
樣例輸出 sampleoutput [複製資料]
4 3 2 1 5
資料範圍和注釋 hint
n,m<=100000
題解:終於a了這道題,好激動。。。
也終於找到了乙個好的splay模版
向序列之神--splay進發!
**:
1view codeconst maxn=100000+100;2
var s,id,fa:array[0..maxn] of
longint;
3 rev:array[0..maxn] of
boolean;
4 c:array[0..maxn,0..1] of
longint;
5i,n,m,rt,x,y:longint;
6procedure swap(var
x,y:longint);
7var
t:longint;
8begin
9 t:=x;x:=y;y:=t;
10end;11
12procedure
pushup(x:longint);
13begin
14 s[x]:=s[c[x,0]]+s[c[x,1]]+1;15
end;
16procedure
pushdown(x:longint);
17var
l,r:longint;
18begin
19 l:=c[x,0];r:=c[x,1
];20
if rev[x] then
21begin
22 swap(c[x,0],c[x,1
]);23 rev[l]:=not
(rev[l]);
24 rev[r]:=not
(rev[r]);
25 rev[x]:=false;
26end;27
end;
28procedure rotate(x:longint;var
k:longint);
29var
l,r,y,z:longint;
30begin
31 y:=fa[x];z:=fa[y];
32if c[y,0]=x then l:=0
else l:=1;r:=l xor 1;33
if y=k then k:=x else c[z,ord(c[z,1]=y)]:=x;
34 fa[x]:=z;fa[y]:=x;fa[c[x,r]]:=y;
35 c[y,l]:=c[x,r];c[x,r]:=y;
36pushup(y);pushup(x);
37end;38
procedure splay(x:longint;var
k:longint);
39var
y,z:longint;
40begin
41while x<>k do
42begin
43 y:=fa[x];z:=fa[y];
44if y<>k then
45begin
46if (c[z,0]=y) xor (c[y,0]=x) then
rotate(x,k)
47else
rotate(y,k);
48end;49
rotate(x,k);
50end;51
end;
52function
find(x,rank:longint):longint;
53var
l,r:longint;
54begin
55 pushdown(x);l:=c[x,0];r:=c[x,1
];56
if s[l]+1=rank then
exit(x)
57else
if s[l]>=rank then
exit(find(l,rank))
58else exit(find(r,rank-s[l]-1
));59
end;
60procedure
rever(l,r:longint);
61var
x,y:longint;
62begin
63 x:=find(rt,l);y:=find(rt,r+2
);64 splay(x,rt);splay(y,c[x,1
]);65 rev[c[y,0]]:=not(rev[c[y,0
]]);
66end;67
procedure
build(l,r,f:longint);
68var
mid,now,last:longint;
69begin
70if l>r then
exit;
71 now:=id[l];last:=id[f];
72if l=r then
73begin
74 fa[now]:=last;s[now]:=1
;75 c[last,ord(l>f)]:=now;
76exit;
77end
;78 mid:=(l+r)>>1
;79 build(l,mid-1,mid);build(mid+1
,r,mid);
80 now:=id[mid];pushup(mid);
81 fa[now]:=last;
82 c[last,ord(mid>f)]:=now;
83end;84
procedure
init;
85begin
86readln(n,m);
87for i:=1
to n+2
do id[i]:=i;
88 build(1,n+2,0);rt:=(n+3)>>1;89
end;
90procedure
main;
91begin
92for i:=1
to m do
93begin
94readln(x,y);
95rever(x,y);
96end;97
for i:=2
to n+1
do write(find(rt,i)-1,'');
98end;99
begin
100 assign(input,'
input.txt
');assign(output,'
output.txt');
101reset(input);rewrite(output);
102init;
103main;
104close(input);close(output);
105end
.106
Tyvj 1729 文藝平衡樹
題面如下 time limit 1 sec memory limit 128 mb 您需要寫一種資料結構 可參考題目標題 來維護乙個有序數列,其中需要提供以下操作 翻轉乙個區間,例如原有序序列是5 4 3 2 1,翻轉區間是 2,4 的話,結果是5 2 3 4 1 第一行為n,m n表示初始序列有n...
bzoj3223 Tyvj 1729 文藝平衡樹
傳送門 description input 第一行為n,m n表示初始序列有n個數,這個序列依次是 1,2 n 1,n m表示翻轉操作次數 接下來m行每行兩個數 l,r 資料保證 1 l r n output 輸出一行n個數字,表示原始序列經過m次變換後的結果 sample input 5 31 3...
BZOJ3223 Tyvj1729 文藝平衡樹
題目大意 一開始有個數列 有q 次區間翻轉操作。請輸出最後的序列。1 n,q 105一道寫出blog都不知道有什麼意義的splay大裸題。splay在我還是pas黨的時候寫過,現在已經忘了個精光。就當做是模板記錄,以及作為自己終於下定決心怒剛專題的紀念吧。什麼你告訴我你不知道這題怎麼做?那我也沒辦法...