【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 }
弱弱地说一句,本蒟蒻码字也不容易,转载请注明出处http://www.cnblogs.com/Maki-Nishikino/p/6247021.html