山东济南彤昌机械科技有限公司 山东济南江鹏工贸游有限公司

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

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 简化题目

 

posted on 2015-12-04 14:35  hahalidaxin  阅读(294)  评论(0编辑  收藏  举报