tyvj 1729 文艺平衡树
文艺平衡树
From admin
背景 Background
此为平衡树系列第二道:文艺平衡树
描述 Description
您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:
翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 4 1
翻转一个区间,例如原有序序列是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
接下来m行每行两个数[l,r] 数据保证 1<=l<=r<=n
输出格式 OutputFormat
输出一行n个数字,表示原始序列经过m次变换后的结果
样例输入 SampleInput [复制数据]
5 3
1 3
1 3
1 4
数据范围和注释 Hint
n,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 begin 100 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