## 3223: Tyvj 1729 文艺平衡树

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

5 3

1 3

1 3

1 4

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
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() {
104     spaly.init(n+1);     //在开始添加虚拟结点
105     int l,r;
106     Node *left,*right,*mid;
107     while(m--) {
117 }