【splay】文艺平衡树 BZOJ 3223

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。第一道是文本编辑器,但是本地测AC,提交的话就WA到死。。

   只有区间翻转操作,如果我们要翻转[L,R]的话,就将L-1转到根,再将第R+1大的转到根的右子树。把根的右子树的左子树打上翻转标记就行了。

   [1,L-1]和[R+1,n]都被转到别的地方去了,所以不会被旋转。

   然后别的都是splay的基本操作啦~只要每次记得push_down就行啦~

  1 #include <iostream>
  2 #include <cstring>
  3 #include <string>
  4 #include <cstdio>
  5 #include <cstdlib>
  6 #include <cmath>
  7 #include <algorithm>
  8 #include <queue>
  9 #include <stack>
 10 #include <map>
 11 #include <set>
 12 #include <list>
 13 #include <vector>
 14 #include <ctime>
 15 #include <functional>
 16 #define pritnf printf
 17 #define scafn scanf
 18 #define sacnf scanf
 19 #define For(i,j,k) for(int i=(j);i<=(k);(i)++)
 20 #define Clear(a) memset(a,0,sizeof(a))
 21 using namespace std;
 22 typedef unsigned int Uint;
 23 const int INF=0x3fffffff;
 24 ///==============struct declaration==============
 25 struct Node{
 26    int Val;bool Rev;
 27    int siz;
 28    Node *lc,*rc;
 29    Node(){lc=rc=NULL;Rev=false;siz=1;}
 30 };
 31 ///==============var declaration=================
 32 const int MAXN=100050;
 33 int n,q;
 34 int num[MAXN];
 35 Node *root=NULL;
 36 ///==============function declaration============
 37 void BuildTree(int l,int r,Node *&o);
 38 int find_kth(int rank,Node *&o);
 39 void Splay(int Rank,Node *&o);
 40 void Rrotate(Node *&x);void Lrotate(Node *&x);
 41 void push_down(Node *&x);void Output(Node *&x);
 42 void update(Node *&x);void TestOutput(Node *&x);
 43 ///==============main code=======================
 44 int main()
 45 {
 46 #define FILE__
 47 #ifdef FILE__
 48    freopen("input","r",stdin);
 49    freopen("output","w",stdout);
 50 #endif
 51    scanf("%d%d",&n,&q);
 52    BuildTree(0,n+1,root);//TestOutput(root);printf("\n");
 53    while (q--){
 54       int L,R;scanf("%d%d",&L,&R);
 55       if (L==R)   continue;
 56       Splay(L,root);
 57       if (root->lc==NULL)
 58          Splay(R+1,root->rc);
 59       else
 60          Splay(R+1-root->lc->siz,root->rc);
 61       if (root->rc!=NULL&&root->rc->lc!=NULL)
 62          root->rc->lc->Rev^=1;
 63       //TestOutput(root);printf("\n");
 64    }
 65    Output(root);
 66    return 0;
 67 }
 68 ///================fuction code====================
 69 void BuildTree(int l,int r,Node *&o){
 70    int m=(l+r)>>1;
 71    o=new(Node);o->Val=m;
 72    if (l==r)   return;
 73    if (m>l) BuildTree(l,m-1,o->lc);
 74    if (m<r) BuildTree(m+1,r,o->rc);
 75    if (o->lc!=NULL)  o->siz+=o->lc->siz;
 76    if (o->rc!=NULL)  o->siz+=o->rc->siz;
 77 }
 78 void Lrotate(Node *&x){
 79    push_down(x);push_down(x->lc);
 80    Node *y=x->lc;
 81    x->lc=y->rc;
 82    y->rc=x;x=y;
 83    update(x->rc);update(x);
 84 }
 85 void Rrotate(Node *&x){
 86    push_down(x);push_down(x->rc);
 87    Node *y=x->rc;
 88    x->rc=y->lc;
 89    y->lc=x;x=y;
 90    update(x->lc);update(x);
 91 }
 92 void push_down(Node *&x){
 93    if (x->Rev){
 94       swap(x->lc,x->rc);
 95       x->Rev=false;
 96       if (x->lc!=NULL)  x->lc->Rev^=1;
 97       if (x->rc!=NULL)  x->rc->Rev^=1;
 98    }
 99 }
100 void update(Node *&x){
101    x->siz=1;
102    if (x->lc!=NULL)  x->siz+=x->lc->siz;
103    if (x->rc!=NULL)  x->siz+=x->rc->siz;
104 }
105 void Splay(int Rank,Node *&o){
106    int ls=0;push_down(o);
107    if (o->lc!=NULL)  ls=o->lc->siz;
108    if (Rank==ls+1)   return;
109    if (Rank>ls+1){
110       Splay(Rank-ls-1,o->rc);
111       Rrotate(o);
112    }
113    else{
114       Splay(Rank,o->lc);
115       Lrotate(o);
116    }
117 }
118 void Output(Node *&x){
119    if (x==NULL) return;
120    push_down(x);
121    Output(x->lc);
122    if (x->Val!=0&&x->Val!=n+1)
123       printf("%d ",x->Val);
124    Output(x->rc);
125 }
126 void TestOutput(Node *&x){
127    if (x==NULL)  return;
128    if (!x->Rev){
129       printf("%d(",x->Val);
130       TestOutput(x->lc);
131       printf(",");
132       TestOutput(x->rc);
133       printf(")");
134    }
135    else{
136       printf("%d(",x->Val);
137       TestOutput(x->rc);
138       printf(",");
139       TestOutput(x->lc);
140       printf(")");
141    }
142 }
BZOJ 3223

  那个TestOutput是我用来在不改变标记的情况下看数的结构的。

posted @ 2015-03-11 11:56  Houjikan  阅读(209)  评论(0编辑  收藏  举报