bzoj3223 Tyvj 1729 文艺平衡树(Splay Tree+区间翻转)
3223: Tyvj 1729 文艺平衡树
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 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
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 简化题目
posted on 2015-12-04 14:35 hahalidaxin 阅读(330) 评论(0) 编辑 收藏 举报