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

同样是非旋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 }

 

posted @ 2017-10-06 14:42  Z-Y-Y-S  阅读(217)  评论(0编辑  收藏  举报