【codevs 4543】普通平衡树

来源:互联网 发布:独立网络经纪人登录 编辑:程序博客网 时间:2024/05/22 00:37

题目>>http://codevs.cn/problem/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;        }    }}
原创粉丝点击