1. 程式人生 > >【codevs 4543】普通平衡樹

【codevs 4543】普通平衡樹

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int MAXN = 1e6 + 5;
int son[MAXN][2],fa[MAXN],sz[MAXN],cnt[MAXN],key[MAXN],n,a,b;
int size = 0,root = 0;
inline void clear(int x)
{
    son[x][0] = son[x][1] = fa[x] = sz[x] = cnt[x] = key[x] = 0
; } inline bool get(int x) { return son[fa[x]][1] == x; } inline void hs(int x) { if(x) { sz[x] = cnt[x]; if(son[x][0]) sz[x] += sz[son[x][0]]; if(son[x][1]) sz[x] += sz[son[x][1]]; } } inline void xuanz(int x) { int y = fa[x],z = fa[y]; bool wh = get(x); son[y][wh] = son[x][wh^1
]; fa[son[x][wh^1]] = y;son[x][wh^1] = y; fa[x] = z;fa[y] = x; if(z) son[z][son[z][1] == y] = x; hs(y);hs(x); } inline void splay(int x) { for(int f;f = fa[x];xuanz(x)) if(fa[f]) xuanz(get(x) == get(f)?f:x); root = x; } inline void insert(int x) { if
(root == 0) { son[size][0] = son[size][1] = fa[++size] = 0; root = size;sz[size] = cnt[size] = 1;key[size] = x; return; } int now = root,f = 0; while(1) { if(x == key[now]) { cnt[now] ++; if(now == root) hs(now); splay(now);break; } f = now;now = son[now][key[now] < x]; if(now == 0) { son[size][0] = son[++size][1] = 0; fa[size] = f;sz[size] = cnt[size] = 1; son[f][key[f] < x] = size; key[size] = x;splay(size); break; } } } inline int find(int x) { int now = root,ans = 0; while(1) { if(x < key[now]) now = son[now][0]; else { ans += son[now][0] ? sz[son[now][0]] : 0; if(x == key[now]) { splay(now); return ans + 1; } ans += cnt[now]; now = son[now][1]; } } } inline int findx(int x) { int now = root; while(1) { if(son[now][0]&&x <= sz[son[now][0]]) now = son[now][0]; else { int temp = (son[now][0] ? sz[son[now][0]] : 0) + cnt[now]; if(x <= temp) return key[now]; x -= temp;now = son[now][1]; } } } inline int pre() { int now = son[root][0]; while(son[now][1]) now = son[now][1]; return now; } inline int nex() { int now = son[root][1]; while(son[now][0]) now = son[now][0]; return now; } inline void del(int x) { int we = find(x); if(cnt[root] > 1) { cnt[root] --; hs(root); return; } if(!son[root][0]&&!son[root][1]) { clear(root); root = 0; return; } if(!son[root][0]) { int now = root;root = son[root][1]; fa[root] = 0; clear(now); return; } if(!son[root][1]) { int now = root;root = son[root][0]; fa[root] = 0; clear(now); return; } int l = pre(),f = root; splay(l); son[root][1] = son[f][1]; fa[son[f][1]] = root; clear(f); hs(root); } int main() { scanf("%d",&n); for(int i = 1;i <= n;i ++) { scanf("%d%d",&a,&b); switch(a) { case 1: insert(b);break; case 2: del(b);break; case 3: cout<<find(b)<<'\n';break; case 4: cout<<findx(b)<<'\n';break; case 5: insert(b);cout<<key[pre()]<<'\n';del(b);break; case 6: insert(b);cout<<key[nex()]<<'\n';del(b);break; } } }