# BZOJ 3223 文艺平衡树

5 3

1 3

1 3

1 4

4 3 2 1 5

N,M<=100000

## Source

splay区间操作大裸题不解释。

  1 #include<queue>
2 #include<cstdio>
3 #include<cstdlib>
4 using namespace std;
5
6 #define maxn 100010
7 const int inf = 1 << 30;
8 queue <int> team;
9 struct TREE
10 {
11     int ch[maxn][2],fa[maxn],cnt,root;
12     int key[maxn],size[maxn],t[maxn];
13
14     inline int newnode()
15     {
16         if (team.empty()) return ++cnt;
17         int ret = team.front(); team.pop();
18         return ret;
19     }
20
21     inline TREE()
22     {
23         root = newnode();
24         key[root] = -inf; ++t[root];
25         updata(root);
27     }
28
29     inline int find(int rank,int have,int now)
30     {
31         if (have+size[ch[now][0]]<rank&&have+size[ch[now][0]]+t[now]>=rank) return now;
32         if (have+size[ch[now][0]]+t[now]<rank) return find(rank,have+size[ch[now][0]]+t[now],ch[now][1]);
33         else return find(rank,have,ch[now][0]);
34     }
35
36     inline void updata(int now) { size[now] = size[ch[now][0]] + size[ch[now][1]] + t[now]; }
37
38     inline void rotate(int x)
39     {
40         int y = fa[x],z = fa[y],l = ch[y][0] != x,r = l ^ 1;
41         if (z != 0) ch[z][ch[z][0] != y] = x;
42         fa[x] = z; fa[y] = x; fa[ch[x][r]] = y;
43         ch[y][l] = ch[x][r]; ch[x][r] = y;
44         updata(y); updata(x);
45     }
46
47     inline void splay(int x,int aim)
48     {
49         int p = fa[aim];
50         while (fa[x] != p)
51         {
52             int y = fa[x],z = fa[y];
53             if (z != p)
54             {
55                 if ((ch[z][0] == y)^(ch[y][0] == x)) rotate(x);
56                 else rotate(y);
57             }
58             rotate(x);
59         }
60         if (aim == root) root = x;
61     }
62
63     inline int search(int x)
64     {
65         int now = root;
66         while (now)
67         {
68             if (key[now] == x) break;
69             now = ch[now][x > key[now]];
70         }
71         return now;
72     }
73
75     {
76         int now = root,pre = 0;
77         while (now)
78         {
79             pre = now;
80             now = ch[now][x > key[now]];
81         }
82         now = newnode();
83         fa[now] = pre; ch[pre][x > key[pre]] = now;
84         key[now] = x; ++t[now];
85         pre = now;
86         while (now)
87         {
88             updata(now);
89             now = fa[now];
90         }
91         splay(pre,root);
92     }
93
94     inline int qrank(int x)
95     {
96         int now = root,ret = 0;
97         while (key[now] != x)
98         {
99             if (x < key[now]) now = ch[now][0];
100             else ret += size[ch[now][0]] + t[now],now = ch[now][1];
101         }
102         return ret + size[ch[now][0]] + 1;
103     }
104
105     inline void insert(int x)
106     {
107         int p = search(x);
108         if (p)
109         {
110             splay(p,root);
111             ++t[p];
112             updata(p);
113         }
115     }
116
117     inline void del(int x)
118     {
119         int now = search(x),k = qrank(x);
120         int p = find(k-1,0,root),q = find(k + t[now],0,root);
121         splay(p,root);
122         splay(q,ch[p][1]);
123         if (--t[now])
124         {
125             updata(now);
126             updata(q);
127             updata(p);
128         }
129         else
130         {
131             ch[q][0] = 0; fa[now] = 0;
132             updata(q);
133             updata(p);
134             team.push(now);
135         }
136     }
137
138     inline int ask(int x,int sign)
139     {
140         int now = root,ret;
141         while (now)
142         {
143             if (sign)
144             {
145                 if (key[now] > x)
146                     ret = now,now = ch[now][0];
147                 else now = ch[now][1];
148             }
149             else
150             {
151                 if (key[now] < x)
152                     ret = now,now = ch[now][1];
153                 else now = ch[now][0];
154             }
155         }
156         return key[ret];
157     }
158 }tree;
159
161 {
162     int x=0,f=1;char ch=getchar();
163     while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
164     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
165     return x*f;
166 }
167
168 int main()
169 {
170     freopen("3224.in","r",stdin);
171     freopen("3224.out","w",stdout);
173     while (T--)
174     {
176         if (opt == 1) tree.insert(read());
177         else if (opt == 2) tree.del(read());
178         else if (opt == 3) printf("%d\n",tree.qrank(read())-1);
179         else if (opt == 4) printf("%d\n",tree.key[tree.find(read()+1,0,tree.root)]);
185 }