bzoj3223 Tyvj 1729 文艺平衡树(Splay Tree+区间翻转)

来源:互联网 发布:如何编写安卓软件 编辑:程序博客网 时间:2024/06/07 17:03

3223: Tyvj 1729 文艺平衡树

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 2202  Solved: 1226
[Submit][Status][Discuss]

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 Tree处理区间翻转。

       分裂后打标记,然后合并即可。

【代码】

  1 #include<cstdio>  2 #include<vector>  3 #include<cstring>  4 #include<iostream>  5 #define FOR(a,b,c) for(int a=(b);a<=(c);a++)  6 using namespace std;  7   8 const int maxn = 200000+10;  9 struct Node{ 10     Node* ch[2]; 11     int v,s,flip; 12     int cmp(int k) { 13         int d=k-ch[0]->s; 14         if(d==1) return -1; 15         return d<=0? 0:1; 16     } 17     void maintain() { 18         s=ch[0]->s+ch[1]->s+1; 19     } 20     void pushdown() { 21         if(flip) { 22             flip=0; 23             swap(ch[0],ch[1]); 24             ch[0]->flip^=1; 25             ch[1]->flip^=1; 26         } 27     } 28 }; 29 Node* null=new Node(); 30 void rotate(Node* &o,int d) { 31     Node* k=o->ch[d^1]; o->ch[d^1]=k->ch[d]; k->ch[d]=o; 32     o->maintain(),k->maintain(); o=k; 33 } 34 void splay(Node* &o,int k) { 35     o->pushdown(); 36     int d=o->cmp(k); 37     if(d==1) k-=o->ch[0]->s+1; 38     if(d!=-1) { 39         Node* p=o->ch[d]; 40         p->pushdown(); 41         int d2=p->cmp(k); 42         int k2=d2==0? k:k-p->ch[0]->s-1; 43         if(d2!=-1) { 44             splay(p->ch[d2],k2); 45             if(d==d2) rotate(o,d^1); else rotate(o->ch[d],d); 46         } 47         rotate(o,d^1); 48     } 49 } 50 Node* merge(Node* left,Node* right) { 51     splay(left,left->s); 52     left->ch[1]=right,left->maintain(); 53     return left; 54 } 55 void split(Node* o,int k,Node* &left,Node* &right) { 56     splay(o,k); 57     left=o,right=left->ch[1],left->ch[1]=null; 58     left->maintain(); 59 } 60 struct SplaySequence { 61     int n; 62     Node seq[maxn]; 63     Node* root; 64      65     Node* build(int sz) { 66         if(!sz) return null; 67         Node* l=build(sz/2); 68         Node* o=&seq[++n]; 69         o->v=n; 70         o->ch[0]=l; 71         o->ch[1]=build(sz-sz/2-1); 72         o->flip=o->s=0; 73         o->maintain(); 74         return o; 75     } 76     void init(int sz) { 77         n=null->s=0; 78         root=build(sz); 79     } 80 }spaly; 81 vector<int> ans; 82 void print(Node* o) { 83     if(o!=null) { 84         o->pushdown(); 85         print(o->ch[0]); 86         ans.push_back(o->v); 87         print(o->ch[1]); 88     } 89 } 90  91 int read() { 92     char c=getchar(); 93     while(!isdigit(c)) c=getchar(); 94     int x=0; 95     while(isdigit(c)) { 96         x=x*10+c-'0'; 97         c=getchar(); 98     } 99     return x;100 }101 int n,m;102 int main() {103     n=read(),m=read();104     spaly.init(n+1);     //在开始添加虚拟结点 105     int l,r;106     Node *left,*right,*mid;107     while(m--) {108         l=read(),r=read();109         split(spaly.root,l,left,right);110         split(right,r-l+1,mid,right);111         mid->flip^=1;112         spaly.root = merge(merge(left,mid),right);113     }114     print(spaly.root);115     for(int i=1;i<ans.size();i++) printf("%d ",ans[i]-1);116     return 0;117 }

PS:UVA 11922 Permutation Transformer 简化题目

 

0 0
原创粉丝点击