Splay的初步學習

具體是啥,qwq

有時間再補吧,貼一下代碼;

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstring>
#define MAXN 10086666
using namespace std;
int f[MAXN],cnt[MAXN],value[MAXN];
int sons[MAXN][2],sub_size[MAXN];
int root,whole_size;
int m,num,be_dealt;
inline int read()
{
    int x = 0;
    int f = 1;
    char ch = getchar();
    while(!isdigit(ch))
    {
        if(ch == '-')
        f = -1;
        ch = getchar();
    }
    while(isdigit(ch))
    {
        x = x * 10 + ch - 48;
        ch = getchar();
    }
    return x * f;
}
inline void S_clear(int x)
{
    sons[x][0] = sons[x][1] = 0;
    f[x] = cnt[x] = value[x] = 0;
    sub_size[x] = 0;
}
inline bool get_which(int x)
{
    return sons[f[x]][1] == x;
}
inline void update(int x)
{
    if(x)
    {
        sub_size[x] = cnt[x];
        if(sons[x][0])
        sub_size[x] += sub_size[sons[x][0]];
        if(sons[x][1])
        sub_size[x] += sub_size[sons[x][1]];
    }
    return ;
}
inline void rotate(int x)
{
    int father = f[x];
    int g_father = f[father];
    int which_son = get_which(x);
    sons[father][which_son] = sons[x][which_son ^ 1];
    f[sons[father][which_son]] = father;
    sons[x][which_son ^ 1] = father;
    f[father] = x;
    f[x] = g_father;
    if(g_father)
    sons[g_father][sons[g_father][1] == father] = x;
    update(father);
    update(x);
}
inline void splay(int x)
{
    for(int fa;fa = f[x];rotate(x))
    if(f[fa])
    rotate((get_which(x)) == get_which(fa) ? fa : x);
    root = x;
}
inline void insert(int x)
{
    if(!root)
    {
        whole_size++;
        sons[whole_size][0] = sons[whole_size][1] = f[whole_size] = 0;
        root = whole_size;
        sub_size[whole_size] = cnt[whole_size]++;
        value[whole_size] = x;
        return ;
    }
    int now = root;
    int fa = 0;
    while(1)
    {
        if(x == value[now])
        {
            cnt[now]++;
            update(now);
            update(fa);
            splay(now);
            break;
        }
        fa = now;
        now = sons[now][value[now] < x];
        if(!now)
        {
            whole_size++;
            sons[whole_size][0] = sons[whole_size][1] = 0;
            f[whole_size] = fa;
            sub_size[whole_size] = cnt[whole_size] = 1;
            sons[fa][value[fa] < x] = whole_size;
            value[whole_size] = x;
            update(fa);
            splay(whole_size);
            break;
        }
    }
}
inline int find_sum(int x)
{
    int now = root;
    while(1)
    {
        if(sons[now][0] && x <= sub_size[sons[now][0]])
        now = sons[now][0];
        else
        {
            int temp = (sons[now][0] ? sub_size[sons[now][0]] : 0) + cnt[now];
            if(x <= temp)
            return value[now];
            x -= temp;
            now = sons[now][1];
        }
    }
}
inline int find_num(int x)
{
    int now = root;
    while(1)
    {
        if(sons[now][0] && x <= sub_size[sons[now][0]])
        now = sons[now][0];
        else
        {
            int temp = (sons[now][0] ? sub_size[sons[now][0]] : 0) + cnt[now];
            if(x <= temp)
            return value[now];
            x -= temp;
            now = sons[now][1];
        }
    }
}
inline int find_rank(int x)
{
    int now = root;
    int ans = 0;
    while(1)
    {
        if(x < value[now])
        now = sons[now][0];
        else
        {
            ans += (sons[now][0] ? sub_size[sons[now][0]] : 0);
            if(x >= value[now])
            {
                splay(now);
                return ans + 1;
            }
            ans += cnt[now];
            now = sons[now][1];
        }
    }
}
inline int find_pre()
{
    int now = sons[root][0];
    while(sons[now][1])
    now = sons[now][1];
    return now;
}
inline int find_suffix()
{
    int now = sons[root][1];
    while(sons[now][0])
    now = sons[now][0];
    return now;
}
inline void my_delete(int x)
{
    int kkk = find_rank(x);
    if(cnt[root] > 1)
    {
        cnt[root]--;
        update(root);
        return ;
    }
    if(!sons[root][0] && !sons[root][1])
    {
        S_clear(root);
        root = 0;
        return ;
    }
    if(!sons[root][0])
    {
        int old_root = root;
        root = sons[root][1];
        f[root] = 0;
        S_clear(old_root);
        return ;
    }
    else
    if(!sons[root][1])
    {
        int old_root = root;
        root = sons[root][0];
        f[root] = 0;
        S_clear(old_root);
        return ;
    }
    int left_max = find_pre();
    int old_root = root;
    splay(left_max);
    sons[root][1] = sons[old_root][1];
    f[sons[old_root][1]] = root;
    S_clear(old_root);
    update(root);
}
int main()
{
    scanf("%d",&m);
    for(int i=1;i<=m;i++)
    {
        num = read();
        be_dealt = read();
        switch(num)
        {
            case 1 : insert(be_dealt);break;
            case 2 : my_delete(be_dealt);break;
            case 3 : printf("%d\n",find_rank(be_dealt));break;
            case 4 : printf("%d\n",find_num(be_dealt));break;
            case 5 : insert(be_dealt);printf("%d\n",value[find_pre()]);my_delete(be_dealt);break;
            case 6 : insert(be_dealt);printf("%d\n",value[find_suffix()]);my_delete(be_dealt);break;
        }
    }
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章