[Tyvj 1729] 文艺平衡树

题面如下:

Tyvj 1729 文艺平衡树

Time Limit: 1 Sec  Memory Limit: 128 MB

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

啊,又是一道板子题

题目要求支持的操作只有区间翻转,其中定位需要维护$size$,翻转要维护翻转标记,所以总体来说还是比较好写的.Splay写这题思路也很明确,每次Splay区间左/右端点的左/右边结点到根/根的右孩子,然后对根的右子结点的左子树打翻转标记即可w

直接贴代码w

GitHub

  1 /*********************************
  2       Judge Result:Accepted
  3 
  4 *********************************/
  5 #include <cstdio>
  6 #include <vector>
  7 #include <cstring>
  8 #include <cstring>
  9 #include <iostream>
 10 #include <algorithm>
 11 
 12 #define lch chd[0]
 13 #define rch chd[1]
 14 #define kch chd[k]
 15 #define xch chd[k^1]
 16 
 17 const int INF=0x2FFFFFFF;
 18 
 19 class SplayTree{
 20 private:
 21     struct Node{
 22         int k;
 23         int sz;
 24         bool rev;
 25         Node* prt;
 26         Node* chd[2];
 27         Node(const int& key){
 28             this->k=key;
 29             this->sz=1;
 30             this->prt=NULL;
 31             this->lch=NULL;
 32             this->rch=NULL;
 33             this->rev=false;
 34         }
 35         ~Node(){
 36             if(this->lch!=NULL)
 37                 delete this->lch;
 38             if(this->rch!=NULL)
 39                 delete this->rch;
 40         }
 41         inline void Maintain(){
 42             if(this!=NULL)
 43                 this->sz=this->lch->size()+this->rch->size()+1;
 44         }
 45         inline void Swap(){
 46             if(this!=NULL){
 47                 this->rev=!this->rev;
 48                 std::swap(this->lch,this->rch);
 49             }
 50         }
 51         inline void PushDown(){
 52             if(this->rev){
 53                 this->rev=false;
 54                 this->lch->Swap();
 55                 this->rch->Swap();
 56             }
 57         }
 58         inline int key(){
 59             return this==NULL?0:this->k;
 60         }
 61         inline int size(){
 62             return this==NULL?0:this->sz;
 63         }
 64     }*root;
 65     inline void Rotate(Node* root,int k){
 66         Node* tmp=root->xch;
 67         root->PushDown();
 68         tmp->PushDown();
 69         tmp->prt=root->prt;
 70         if(root->prt==NULL)
 71             this->root=tmp;
 72         else if(root->prt->lch==root)
 73             root->prt->lch=tmp;
 74         else
 75             root->prt->rch=tmp;
 76         root->xch=tmp->kch;
 77         if(tmp->kch!=NULL)
 78             tmp->kch->prt=root;
 79         tmp->kch=root;
 80         root->prt=tmp;
 81         root->Maintain();
 82         tmp->Maintain();
 83     }
 84     void Splay(Node* root,Node* prt=NULL){
 85         while(root->prt!=prt){
 86             int k=root->prt->lch==root;
 87             if(root->prt->prt==prt){
 88                 Rotate(root->prt,k);
 89             }
 90             else{
 91                 int d=root->prt->prt->lch==root->prt;
 92                 Rotate(k==d?root->prt->prt:root->prt,k);
 93                 Rotate(root->prt,d);
 94             }
 95         }
 96     }
 97     Node* Build(const std::vector<int>& v,int l,int r){
 98         if(l>r)
 99             return NULL;
100         int mid=(l+r)>>1;
101         Node* tmp=new Node(v[mid]);
102         tmp->lch=Build(v,l,mid-1);
103         tmp->rch=Build(v,mid+1,r);
104         if(tmp->lch!=NULL)
105             tmp->lch->prt=tmp;
106         if(tmp->rch!=NULL)
107             tmp->rch->prt=tmp;
108         tmp->Maintain();
109         return tmp;
110     }
111     void PrintTree(Node* root,int deep){
112         for(int i=0;i<deep;i++)
113             fputc(' ',stderr);
114         fprintf(stderr, "(root=0x%X,key=%dsize=%d)\n", root,root->key(),root->size());
115         if(root==NULL)
116             return;
117         PrintTree(root->lch,deep+1);
118         PrintTree(root->rch,deep+1);
119     }
120 public:
121     SplayTree(){
122         this->root=new Node(-INF);
123         this->root->rch=new Node(-INF);
124         this->root->rch->prt=this->root;
125     }
126     SplayTree(const std::vector<int>& v){
127         this->root=Build(v,0,v.size()-1);
128     }
129     ~SplayTree(){
130         delete this->root;
131     }
132     Node* Kth(int pos){
133         ++pos;
134         Node* root=this->root;
135         while(root!=NULL){
136             root->PushDown();
137             int k=root->lch->size()+1;
138             if(pos<k)
139                 root=root->lch;
140             else if(pos==k)
141                 return root;
142             else{
143                 pos-=k;
144                 root=root->rch;
145             }
146         }
147         return NULL;
148     }
149     inline void Reverse(const int& l,const int& r){
150         this->Splay(this->Kth(l-1));
151         this->Splay(this->Kth(r+1),this->root);
152         this->root->rch->lch->Swap();
153         this->root->rch->Maintain();
154         this->root->Maintain();
155     }
156     inline void Insert(const int& pos,SplayTree* data){
157         this->Splay(this->Kth(pos));
158         this->Splay(this->Kth(pos+1),this->root);
159         Node* tmp=data->root;
160         data->root=NULL;
161         this->root->rch->lch=tmp;
162         tmp->prt=this->root->rch;
163         this->root->rch->Maintain();
164         this->root->Maintain();
165     }
166     void Print(){
167         this->PrintTree(this->root,0);
168     }
169 };
170 
171 int FastRead();
172 
173 int main(){
174     freopen("sph.in","r",stdin);
175     freopen("sph.out","w",stdout);
176     SplayTree* tree=new SplayTree();
177     std::vector<int> v;
178     int n=FastRead();
179     int m=FastRead();
180     int a,b;
181     for(int i=1;i<=n;i++){
182         v.push_back(i);
183     }
184     tree->Insert(0,new SplayTree(v));
185     for(int i=0;i<m;i++){
186         a=FastRead();
187         b=FastRead();
188         tree->Reverse(a,b);
189     }
190     for(int i=1;i<=n;i++){
191         printf("%d ",tree->Kth(i)->key());
192     }
193     putchar('\n');
194     return 0;
195 }
196 
197 int FastRead(){
198     int ans=0;
199     bool neg=false;
200     register char ch=getchar();
201     while(!isdigit(ch)){
202         if(ch=='-')
203             neg=true;
204         ch=getchar();
205     }
206     while(isdigit(ch)){
207         ans=ans*10+ch-'0';
208         ch=getchar();
209     }
210     if(neg)
211         ans=-ans;
212     return ans;
213 }
Backup

然后放图~

 

posted @ 2017-07-24 17:26  rvalue  阅读(226)  评论(0编辑  收藏  举报