#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn = 1000010;
int sz, root;
int ch[maxn][2], cnt[maxn], size[maxn], p[maxn], key[maxn];
inline void clear(int x) {
ch[x][0] = ch[x][1] = cnt[x] = size[x] = p[x] = key[x] = 0;
}
inline int get(int x) {
return ch[p[x]][1] == x;
}
inline void update(int x) {
if(x) {
size[x] = cnt[x];
if(ch[x][0]) size[x] += size[ch[x][0]];
if(ch[x][1]) size[x] += size[ch[x][1]];
}
}
inline void rotate(int x) {
int fa = p[x], gfa = p[p[x]], which = get(x);
ch[fa][which] = ch[x][which^1];
p[ch[fa][which]] = fa;
ch[x][which^1] = fa;
p[fa] = x; p[x] = gfa;
if(gfa)
ch[gfa][ch[gfa][1] == fa] = x;
update(fa); update(x);
}
inline void splay(int x) {
for(int fa; fa = p[x]; rotate(x))
if(p[fa])
rotate((get(x) == get(fa))?fa:x);
root = x;
}
inline void insert(int x) {
int now = root, fa = 0;
if(now == 0) {
sz++; root = sz; key[sz] = x;
ch[sz][0] = ch[sz][1] = p[sz] = 0;
cnt[sz] = size[sz] = 1;
return;
}
while(1) {
if(key[now] == x) {
cnt[now]++;
update(now); update(fa);
splay(now);
return;
}
fa = now, now = ch[now][key[now] < x];
if(now == 0) {
sz++;
ch[sz][0] = ch[sz][1] = 0;
cnt[sz] = size[sz] = 1;
p[sz] = fa; key[sz] = x;
ch[fa][key[fa] < x] = sz;
update(fa);
splay(sz);
return;
}
}
}
int find(int x) {
int now = root, ans = 0;
while(1) {
if(x < key[now])
now = ch[now][0];
else {
ans += (ch[now][0]?size[ch[now][0]]:0);
if(x == key[now]) {
splay(now);
return ans+1;
}
ans += cnt[now];
now = ch[now][1];
}
}
}
int findx(int x) {
int now = root;
while(1) {
if(ch[now][0] && x <= size[ch[now][0]])
now = ch[now][0];
else {
int temp = (ch[now][0]?size[ch[now][0]]:0) + cnt[now];
if(x <= temp)
return key[now];
x -= temp;
now = ch[now][1];
}
}
}
int pre() {
int now = ch[root][0];
while(ch[now][1])
now = ch[now][1];
return now;
}
int next() {
int now = ch[root][1];
while(ch[now][0])
now = ch[now][0];
return now;
}
void del(int x) {
int whatever = find(x);
if(cnt[root] > 1) {
cnt[root]--; update(root);
return;
}
if(!ch[root][0] && !ch[root][1]) {
clear(root); root = 0;
return;
}
if(!ch[root][0]) {
int oldroot = root;
root = ch[root][1]; p[root] = 0;
clear(oldroot);
return;
} else if(!ch[root][1]) {
int oldroot = root;
root = ch[root][0]; p[root] = 0;
clear(oldroot);
return;
}
int bigleft = pre(), oldroot = root;
splay(bigleft);
ch[root][1] = ch[oldroot][1];
p[ch[root][1]] = root;
clear(oldroot);
update(root);
return;
}
/*
10
1 106465
4 1
1 317721
1 460929
1 644985
1 84185
1 89851
6 81968
1 492737
5 493598
*/
int main() {
int n;
scanf("%d", &n);
for(int i = 1; i <= n; i++) {
int t, x;
scanf("%d%d", &t, &x);
switch(t) {
case 1: insert(x); break;
case 2: del(x); break;
case 3: printf("%d\n", find(x)); break;
case 4: printf("%d\n", findx(x)); break;
case 5: insert(x); printf("%d\n", key[pre()]); del(x); break;
case 6: insert(x); printf("%d\n", key[next()]); del(x); break;
}
}
return 0;
}
splay 模板
最新推荐文章于 2019-03-08 21:51:45 发布