您的位置:首页 > 其它

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

2016-03-30 17:31 399 查看

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 简化题目
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: