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
1 3
1 3
1 4
Sample Output
4 3 2 1 5
HINT
N,M<=100000
同样是非旋treap
与splay做这道题的思路一样,交换左右子节点
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 using namespace std; 6 struct Treap 7 { 8 Treap *l,*r; 9 int val,size,lev; 10 bool rev; 11 }S[200001],*pos=S,*root; 12 int n; 13 typedef pair<Treap*,Treap*> Droot; 14 void NewNode(Treap* &r,int val) 15 { 16 r=++pos; 17 r->val=val; 18 r->lev=rand(); 19 r->size=1; 20 r->l=r->r=0; 21 } 22 int getsize(Treap* x) 23 { 24 if (!x) return 0; 25 else return x->size; 26 } 27 void updata(Treap* x) 28 { 29 x->size=1; 30 if (x->l) x->size+=x->l->size; 31 if (x->r) x->size+=x->r->size; 32 } 33 Treap* rever(Treap* x) 34 { 35 if (!x) return 0; 36 swap(x->l,x->r); 37 x->rev^=1; 38 return x; 39 } 40 void pushdown(Treap* x) 41 { 42 if (x->rev) 43 { 44 rever(x->l); 45 rever(x->r); 46 x->rev=0; 47 } 48 } 49 Treap *merge(Treap *A,Treap *B) 50 { 51 if (!A) return B; 52 if (!B) return A; 53 if (A->lev<B->lev) 54 { 55 pushdown(A); 56 A->r=merge(A->r,B); 57 updata(A); 58 return A; 59 } 60 else 61 { 62 pushdown(B); 63 B->l=merge(A,B->l); 64 updata(B); 65 return B; 66 } 67 } 68 Droot split(Treap *x,int k) 69 { 70 if (!x) return Droot(0,0); 71 Droot y; 72 pushdown(x); 73 if (getsize(x->l)>=k) 74 { 75 y=split(x->l,k); 76 x->l=y.second; 77 updata(x); 78 y.second=x; 79 } 80 else 81 { 82 y=split(x->r,k-getsize(x->l)-1); 83 x->r=y.first; 84 updata(x); 85 y.first=x; 86 } 87 return y; 88 } 89 void reverse(int l,int r) 90 { 91 Droot x=split(root,l-1); 92 Droot y=split(x.second,r-l+1); 93 root=merge(merge(x.first,rever(y.first)),y.second); 94 } 95 int main() 96 {int opt,x,q,i,l,r; 97 cin>>n>>q; 98 Treap* rt; 99 for (i=1;i<=n;i++) 100 NewNode(rt,i),root=merge(root,rt); 101 while (q--) 102 { 103 scanf("%d%d",&l,&r); 104 reverse(l,r); 105 } 106 for (i=1;i<=n;i++) 107 { 108 Droot y=split(root,1); 109 printf("%d ",y.first->val); 110 root=y.second; 111 } 112 }