【Splay】bzoj3223-Tyvj1729文艺平衡树

一、题目

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

顺便附上原题链接→_→Problem 3223. -- Tyvj 1729 文艺平衡树

二、代码实现

裸Splay,基本操作都不齐_(:з」∠)_不过这题有个特点,就是关键字和原序列序号是一样的,所以可以少开一个变量(虽然这并没有什么卵用┑( ̄Д  ̄)┍

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int MAXN=1e5+10;
 4 int n,m;
 5 struct node
 6 {
 7     int siz,fa,c[2];
 8     bool rev;//翻转标记
 9 }tr[MAXN];
10 int root;
11 void push_up(int k)
12 {
13     tr[k].siz=tr[tr[k].c[0]].siz+tr[tr[k].c[1]].siz+1;
14     return;
15 }
16 void push_down(int k)
17 {
18     if(tr[k].rev)
19     {
20         swap(tr[k].c[0],tr[k].c[1]);
21         tr[k].rev=0;
22         tr[tr[k].c[0]].rev^=1,tr[tr[k].c[1]].rev^=1;
23     }
24     return;
25 }
26 void rotate(int &k,int x)
27 {
28     int y=tr[x].fa,z=tr[y].fa;
29     bool dy=tr[y].c[1]==x,dz=tr[z].c[1]==y;
30     push_down(y);
31     if(k==y)k=x,tr[x].fa=z;
32     else tr[z].c[dz]=x,tr[x].fa=z;
33     tr[y].c[dy]=tr[x].c[dy^1],tr[tr[x].c[dy^1]].fa=y;
34     tr[x].c[dy^1]=y,tr[y].fa=x;
35     push_up(y);
36     return;
37 }
38 void splay(int &k,int x)
39 {
40     push_down(x);
41     while(k!=x)
42     {
43         int y=tr[x].fa,z=tr[y].fa;
44         if(k!=y)
45         {
46             if(tr[y].c[1]==x^tr[z].c[1]==y)rotate(k,x);
47             else rotate(k,y);
48         }
49         rotate(k,x);
50     }
51     push_up(x);
52     return;
53 }
54 int find(int k,int x)
55 {
56     if(!k)return 0;
57     push_down(k);
58     if(x<=tr[tr[k].c[0]].siz)return find(tr[k].c[0],x);
59     if(x==tr[tr[k].c[0]].siz+1)return k;
60     return find(tr[k].c[1],x-tr[tr[k].c[0]].siz-1);
61 }
62 void print(int k)
63 {
64     if(!k)return;
65     push_down(k);
66     print(tr[k].c[0]);
67     if(k>1&&k<n+2)printf("%d ",k-1);
68     print(tr[k].c[1]);
69 }
70 int main()
71 {
72     scanf("%d%d",&n,&m);
73     for(int i=1;i<=n+2;++i)
74     {
75         tr[i].siz=n+3-i;
76         tr[i].fa=i-1,tr[i].c[1]=i+1;
77     }
78     tr[n+2].c[1]=0,root=1;
79     while(m--)
80     {
81         int l,r;
82         scanf("%d%d",&l,&r);
83         splay(root,find(root,l));
84         splay(tr[root].c[1],find(root,r+2));
85         tr[tr[tr[root].c[1]].c[0]].rev^=1;
86     }
87     print(root);
88     printf("\n");
89     return 0;
90 }
bzoj3223-文艺平衡树

弱弱地说一句,本蒟蒻码字也不容易,转载请注明出处http://www.cnblogs.com/Maki-Nishikino/p/6247021.html

posted @ 2017-01-04 00:19  Maki_Nishikino  阅读(473)  评论(0编辑  收藏  举报