標籤:des style blog http color os strong io
文藝平衡樹
From admin背景 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 3
1 3
1 3
1 4
範例輸出 SampleOutput [複製資料] 4 3 2 1 5 資料範圍和注釋 Hintn,m<=100000 題解:終於A了這道題,好激動。。。也終於找到了一個好的splay模版向序列之神--splay進發!代碼:
1 const 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; 5 i,n,m,rt,x,y:longint; 6 procedure swap(var x,y:longint); 7 var t:longint; 8 begin 9 t:=x;x:=y;y:=t; 10 end; 11 12 procedure pushup(x:longint); 13 begin 14 s[x]:=s[c[x,0]]+s[c[x,1]]+1; 15 end; 16 procedure pushdown(x:longint); 17 var l,r:longint; 18 begin 19 l:=c[x,0];r:=c[x,1]; 20 if rev[x] then 21 begin 22 swap(c[x,0],c[x,1]); 23 rev[l]:=not(rev[l]); 24 rev[r]:=not(rev[r]); 25 rev[x]:=false; 26 end; 27 end; 28 procedure rotate(x:longint;var k:Longint); 29 var l,r,y,z:longint; 30 begin 31 y:=fa[x];z:=fa[y]; 32 if 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; 36 pushup(y);pushup(x); 37 end; 38 procedure splay(x:longint;var k:longint); 39 var y,z:longint; 40 begin 41 while x<>k do 42 begin 43 y:=fa[x];z:=fa[y]; 44 if y<>k then 45 begin 46 if (c[z,0]=y) xor (c[y,0]=x) then rotate(x,k) 47 else rotate(y,k); 48 end; 49 rotate(x,k); 50 end; 51 end; 52 function find(x,rank:longint):longint; 53 var l,r:longint; 54 begin 55 pushdown(x);l:=c[x,0];r:=c[x,1]; 56 if s[l]+1=rank then exit(x) 57 else if s[l]>=rank then exit(find(l,rank)) 58 else exit(find(r,rank-s[l]-1)); 59 end; 60 procedure rever(l,r:longint); 61 var x,y:longint; 62 begin 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]]); 66 end; 67 procedure build(l,r,f:longint); 68 var mid,now,last:longint; 69 begin 70 if l>r then exit; 71 now:=id[l];last:=id[f]; 72 if l=r then 73 begin 74 fa[now]:=last;s[now]:=1; 75 c[last,ord(l>f)]:=now; 76 exit; 77 end; 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; 83 end; 84 procedure init; 85 begin 86 readln(n,m); 87 for i:=1 to n+2 do id[i]:=i; 88 build(1,n+2,0);rt:=(n+3)>>1; 89 end; 90 procedure main; 91 begin 92 for i:=1 to m do 93 begin 94 readln(x,y); 95 rever(x,y); 96 end; 97 for i:=2 to n+1 do write(find(rt,i)-1,‘ ‘); 98 end; 99 begin100 assign(input,‘input.txt‘);assign(output,‘output.txt‘);101 reset(input);rewrite(output);102 init;103 main;104 close(input);close(output);105 end.106
View Code