TYVJ1729 文艺平衡树
TYVJ1729 文艺平衡树
【题目描述】
您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:
翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 4 1
【输入文件】
第一行为n,m n表示初始序列有n个数,这个序列依次是(1,2……n-1,n) m表示翻转操作次数
接下来m行每行两个数[l,r] 数据保证 1<=l<=r<=n
【输出文件】
输出一行n个数字,表示原始序列经过m次变换后的结果
【输入样例】
5 3
1 3
1 3
1 4
【输出样例】
4 3 2 1 5
【数据范围】
N,M<=100000
【题目分析】
对于这种翻转操作线段树无力……只能用平衡树了
Splay还是很有爱滴~
第一次打splay……对于每一次旋转操作l,r,我们把l-1旋转到根,把r+1旋转到根的右儿子,此时根的右儿子的左子树中就是需要翻转的区间了~然后把这棵子树中所有的结点的左右儿子交换就可以了。
每次都交换的复杂度太高,我们采用lazy的方式,每次把翻转操作标记一下,需要访问的时候再交换
【代码实现】
Code
1 program tyvj1729; 2 type tree=record 3 l,r,fa,z,y:longint; 4 bj:boolean; 5 end; 6 var a:array[-1..100001]of tree; 7 z,b,c:array[0..100001]of longint; 8 i,j,m,n,l,r,g,t,x,y:longint; 9 procedure left(i:longint); 10 var j:longint; 11 o:boolean; 12 begin 13 j:=a[i].fa; 14 if a[j].fa<>-1 then 15 if j=a[a[j].fa].l then a[a[j].fa].l:=i 16 else a[a[j].fa].r:=i; 17 a[i].fa:=a[j].fa; 18 a[j].fa:=i; 19 inc(a[i].y,a[j].y+1); 20 dec(a[j].z,a[i].z+1); 21 if a[i].r<>-1 then a[a[i].r].fa:=j; 22 a[j].l:=a[i].r; 23 a[i].r:=j; 24 end; 25 procedure right(i:longint); 26 var j:longint; 27 begin 28 j:=a[i].fa; 29 if a[j].fa<>-1 then 30 if j=a[a[j].fa].l then a[a[j].fa].l:=i 31 else a[a[j].fa].r:=i; 32 a[i].fa:=a[j].fa; 33 a[j].fa:=i; 34 inc(a[i].z,a[j].z+1); 35 dec(a[j].y,a[i].y+1); 36 if a[i].l<>-1 then a[a[i].l].fa:=j; 37 a[j].r:=a[i].l; 38 a[i].l:=j; 39 end; 40 procedure insert(var i:longint;j:longint); 41 begin 42 if j<i then 43 begin 44 if a[i].l=-1 then 45 begin 46 a[i].l:=j; 47 a[j].fa:=i; 48 end 49 else insert(a[i].l,j); 50 inc(a[i].z); 51 end 52 else 53 begin 54 if a[i].r=-1 then 55 begin 56 a[i].r:=j; 57 a[j].fa:=i; 58 end 59 else insert(a[i].r,j); 60 inc(a[i].y); 61 end; 62 end; 63 procedure clean(i:longint); 64 var t:longint; 65 begin 66 a[a[i].l].bj:=not a[a[i].l].bj; 67 a[a[i].r].bj:=not a[a[i].r].bj; 68 t:=a[i].l; 69 a[i].l:=a[i].r; 70 a[i].r:=t; 71 t:=a[i].z; 72 a[i].z:=a[i].y; 73 a[i].y:=t; 74 a[i].bj:=false; 75 end; 76 procedure splay(i:longint;j:longint); 77 var t,k,tmp,p:longint; 78 o:boolean; 79 begin 80 if i=j then exit; 81 while a[j].fa<>i do 82 begin 83 if a[a[j].fa].l=j then o:=true 84 else o:=false; 85 if a[a[j].fa].fa=i then 86 begin 87 if o then left(j) 88 else right(j); 89 end 90 else if a[a[a[j].fa].fa].l=a[j].fa then 91 begin 92 if o then 93 begin 94 left(a[j].fa); 95 left(j); 96 end 97 else 98 begin 99 right(j); 100 left(j); 101 end; 102 end 103 else 104 begin 105 if o then 106 begin 107 left(j); 108 right(j); 109 end 110 else 111 begin 112 right(a[j].fa); 113 right(j); 114 end; 115 end; 116 end; 117 if i=-1 then g:=j; 118 end; 119 function find(i,k:longint):longint; 120 begin 121 if a[i].bj then clean(i); 122 if a[i].z+1=k then exit(i); 123 if a[i].z+1<k then exit(find(a[i].r,k-a[i].z-1)) 124 else exit(find(a[i].l,k)); 125 end; 126 begin 127 readln(n,m); 128 for i:=0 to n+1 do 129 begin 130 a[i].l:=-1; 131 a[i].r:=-1; 132 end; 133 a[0].fa:=-1; 134 g:=0; 135 for i:=1 to n+1 do 136 begin 137 insert(g,i); 138 splay(-1,i); 139 end; 140 for i:=1 to m do 141 begin 142 readln(l,r); 143 x:=find(g,l); 144 y:=find(g,r+2); 145 splay(-1,x); 146 splay(g,y); 147 a[a[y].l].bj:=not a[a[y].l].bj; 148 end; 149 for i:=1 to n do write(find(g,i+1),' '); 150 end.