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.

 

 

 

 

转载于:https://www.cnblogs.com/whitecloth/archive/2012/05/16/2505373.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值