码迷,mamicode.com
首页 > 其他好文 > 详细

【模板】Splay

时间:2019-09-13 18:03:29      阅读:77      评论:0      收藏:0      [点我收藏+]

标签:while   bool   max   include   pre   getchar   cst   inline   cpp   

Splay应该是我目前写过的最长的代码了(188)

#include <iostream>
#include <cstdio>
using namespace std;
//Mystery_Sky
//Splay
#define M 1000100
#define INF 0x3f3f3f3f
#define ll long long
inline int read()
{
    int x=0,f=1; char c=getchar();
    while(c<'0'||c>'9') {if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9') {x=x*10+c-'0';c=getchar();}
    return x*f;
}

int fa[M], val[M], cnt[M], son[M][2], size[M];
int tot, root, n;

inline void S_clear(int p)
{
    son[p][0] = son[p][1] = fa[p] = size[p] = cnt[p] = val[p] = 0;
}

inline void update(int p)
{
    if (p){  
        size[p] = cnt[p];  
        if (son[p][0]) size[p] += size[son[p][0]];  
        if (son[p][1]) size[p] += size[son[p][1]];  
    }  
    return ;
}

inline bool get_which(int p)
{
    return son[fa[p]][1] == p;
}

inline void Rotate(int p)
{
    int father = fa[p], grfa = fa[father], w_son = get_which(p);
    son[father][w_son] = son[p][w_son^1];
    fa[son[father][w_son]] = father;
    son[p][w_son^1] = father;
    fa[father] = p;
    fa[p] = grfa;
    if(grfa) {
        son[grfa][son[grfa][1] == father] = p;
    }
    update(father);
    update(p);
}

inline void Splay(int p)//关键操作。 
{
    for(int f; f = fa[p]; Rotate(p))
        if(fa[f]) Rotate((get_which(p) == get_which(f)) ? f : p);
    root = p;
}

inline void insert(int x)
{
    if(!root) {
        tot++;
        son[tot][0] = son[tot][1] = fa[tot] = 0;
        root = tot;
        size[tot] = cnt[tot]++;
        val[tot] = x;
    }
    int now = root, f = 0;
    while(1) {
        if(x == val[now]) {
            cnt[now]++;
            update(now);
            update(f);
            Splay(now);
            break;
        }
        f = now;
        now = son[now][val[now]<x];
        if(!now) {
            tot++;
            son[tot][0] = son[tot][1] = 0;
            fa[tot] = f;
            size[tot] = cnt[tot] = 1;
            son[f][val[f]<x] = tot;
            val[tot] = x;
            update(f);
            Splay(tot);
            break;
        }
    }
}

inline int query_val(int rank)
{
    int p = root;
    while(1) {
        if(son[p][0] && rank <= size[son[p][0]]) p = son[p][0];
        else {
            int temp = size[son[p][0]] + cnt[p];
            if(rank <= temp) return val[p];
            rank -= temp;
            p = son[p][1];
        }
    }
}

inline int query_rank(int x)
{
    int p = root, ans = 0;
    while(1) {
        if(x < val[p]) p = son[p][0];
        else {
            ans += size[son[p][0]];
            if(x == val[p]) {
                Splay(p);
                return ans + 1;
            }
            ans += cnt[p];
            p = son[p][1];
        }
    }
}

inline int query_pre()
{
    int p = son[root][0];
    while(son[p][1]) p = son[p][1];
    return p;
}

inline int query_next()
{
    int p = son[root][1];
    while(son[p][0]) p = son[p][0];
    return p;
}

inline void Delete(int x)
{
    int rank = query_rank(x);
    if(cnt[root] > 1) {
        cnt[root]--;
        update(root);
        return;
    }
    if(!son[root][0] && !son[root][1]) {
        S_clear(root);
        root = 0;
        return;
    }
    if(!son[root][0]) {
        int old_root = root;
        root = son[root][1];
        fa[root] = 0;
        S_clear(old_root);
        return;
    }
    else if(!son[root][1]) {
        int old_root = root;
        root = son[root][0];
        fa[root] = 0;
        S_clear(old_root);
        return;
    }
    int lmax = query_pre(), old_root = root;
    Splay(lmax);
    son[root][1] = son[old_root][1];
    fa[son[old_root][1]] = root;
    S_clear(old_root);
    update(root);
}

int main() {
    n = read();
    for(int i = 1; i <= n; i++) {
        int opt = read(), x = read();
        if(opt == 1) insert(x);
        else if(opt == 2) Delete(x);
        else if(opt == 3) printf("%d\n", query_rank(x));
        else if(opt == 4) printf("%d\n", query_val(x));
        else if(opt == 5) insert(x), printf("%d\n", val[query_pre()]), Delete(x);
        else if(opt == 6) insert(x), printf("%d\n", val[query_next()]), Delete(x);
    }
    return 0;
}

【模板】Splay

标签:while   bool   max   include   pre   getchar   cst   inline   cpp   

原文地址:https://www.cnblogs.com/Benjamin-cpp/p/11517171.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!