bzoj3223:Tyvj 1729 文艺平衡树

Description

您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 4 1 

Input

第一行为n,m n表示初始序列有n个数,这个序列依次是(1,2……n-1,n)  m表示翻转操作次数
接下来m行每行两个数[l,r] 数据保证 1<=l<=r<=n 

Output

输出一行n个数字,表示原始序列经过m次变换后的结果 

Sample Input

5 3
1 3
1 3
1 4

Sample Output

4 3 2 1 5

HINT

N,M<=100000
题解

splay模版题,比较能体现splay优势的就是区间性的问题了吧。

splay,顾名思义,往死玩。。比较骚的操作就是旋转,利用异或实现,理解难度和treap差不多??

 

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 #define maxn 100005
 5 using namespace std;
 6 int n,m,root;
 7 struct Splay{
 8     int c[2],fa,siz;
 9     bool rev;
10 }a[maxn];
11 void pushup(int o){a[o].siz=a[a[o].c[0]].siz+a[a[o].c[1]].siz+1;}
12 void reserve(int o)
13 {
14     if(!o)return ;
15     swap(a[o].c[0],a[o].c[1]);
16     a[o].rev^=1;
17     return ;
18 }
19 void pushdown(int o)
20 {
21     if(a[o].rev)
22     {
23         reserve(a[o].c[0]);
24         reserve(a[o].c[1]);
25         a[o].rev=false;
26         return ;
27     }
28 }
29 void rotate(int &o,int x)
30 {
31     int y=a[x].fa,z=a[y].fa,dy=a[y].c[1]==x,dz=a[z].c[1]==y;
32     pushdown(y);
33     if(o==y)o=x;
34     else a[z].c[dz]=x;
35     a[x].fa=z;
36     a[y].c[dy]=a[x].c[dy^1];
37     a[a[y].c[dy]].fa=y;
38     a[x].c[dy^1]=y;
39     a[y].fa=x;
40     pushup(y);
41     return ;
42 }
43 void splay(int &o,int x)
44 {
45     pushdown(x);
46     while(o!=x)
47     {    
48         int y=a[x].fa,z=a[y].fa;
49         if(o!=y)
50         {
51             if(x==a[y].c[1]^y==a[z].c[1])rotate(o,x);
52             else rotate(o,y);
53         }
54         rotate(o,x);
55     }
56     pushup(x);
57     return ;
58 }
59 int find(int o,int x)
60 {
61     pushdown(o);
62     if(x<=a[a[o].c[0]].siz)return find(a[o].c[0],x);
63     if(x<=a[a[o].c[0]].siz+1)return o;
64     return find(a[o].c[1],x-1-a[a[o].c[0]].siz);
65 }
66 void print(int o)
67 {
68     if(!o)return ;
69     pushdown(o);
70     print(a[o].c[0]);
71     if(o>1&&o<n+2)printf("%d ",o-1);
72     print(a[o].c[1]);
73     return ;
74 }
75 int main()
76 {
77     scanf("%d%d",&n,&m);
78     a[1].siz=n+2;a[1].c[1]=2;
79     a[n+2].siz=1;a[n+2].fa=n+1;
80     for(int i=1 ; i<=n ; ++i)a[i+1]=(Splay){{0,i+2},i,n+2-i,false};
81     root=1;
82     for(int i=1 ; i<=m ; ++i )
83     {
84         int l,r;
85         scanf("%d%d",&l,&r);
86         r+=2;
87         l=find(root,l);r=find(root,r);
88         splay(root,l);splay(a[root].c[1],r);
89         reserve(a[r].c[0]);
90     }
91     print(root);
92     return 0;
93 }

 

 

 

posted @ 2017-09-19 23:42  傅judge  阅读(124)  评论(0编辑  收藏  举报