• HIT暑期集训 平衡树


    贴几篇网上找的splay入门博客

    https://www.cnblogs.com/cjyyb/p/7499020.html

    https://www.cnblogs.com/santiego/p/10011592.html

    B    HihoCoder 1333

    C    HihoCoder 1034

    D    HDU 4680

    E    计蒜客 T2009

    G    LibreOJ 104

    模板题,参考了网上的treap模板(我不会写啊)

    #include<cstdio>
    #include<algorithm>
    #define maxn 100010
    #define inf 200000000
    using namespace std;
    struct node
    {
        int siz,num,va,pri;
    }e[maxn];
    int son[maxn][2],cnt=0,rt=0;
    void pushup(int k)
    {
        e[k].siz=e[son[k][0]].siz+e[son[k][1]].siz+e[k].num;
    }
    void rotate(int &p,int d)//0左旋1右旋 
    {
        int k=son[p][d^1];//k为p的d^1儿子 
        son[p][d^1]=son[k][d];
        son[k][d]=p;//k的d儿子变为p
        pushup(p);
        pushup(k); 
        p=k;
    } 
    void ins(int &p,int x)//k为当前节点,x为要插入的数字 
    {
        if (!p)//空节点 
        {
            p=++cnt;//赋予节点编号
            e[p].siz=1;
            e[p].num=1;
            e[p].va=x;
            e[p].pri=rand(); 
            return; 
        }
        if (e[p].va==x)
        {
            e[p].siz++;
            e[p].num++;
            return;
        }
        int d;
        if (x>e[p].va) d=1;
        else d=0;
        ins(son[p][d],x);
        if (e[p].pri<e[son[p][d]].pri) rotate(p,d^1);//维护pri大根堆 
        pushup(p);
    }
    void del(int &p,int x)
    {
        if (!p) return;
        if (x<e[p].va) del(son[p][0],x);
        else if (x>e[p].va) del(son[p][1],x);
        else 
        {
            if (!son[p][0] && !son[p][1])//叶子节点,直接删除 
            {
                e[p].num--;
                e[p].siz--;
                if (e[p].num==0) p=0;
            }
            else if (son[p][0] && !son[p][1])//只有一个儿子的情况,把儿子转上来,到子树里解决 
            {
                rotate(p,1);
                del(son[p][1],x);
            }
            else if (!son[p][0] && son[p][1])
            {
                rotate(p,0);
                del(son[p][0],x);
            }
            else if (son[p][0] && son[p][1])//把较大的儿子转上来,去另一个子树里解决 
            {
                int d;
                if (e[son[p][0]].pri>e[son[p][1]].pri) d=1;
                else d=0;
                rotate(p,d);
                del(son[p][d],x);
            }
        }
        pushup(p);
    }
    int rk(int p,int x)
    {
        if (!p) return 0;
        if (e[p].va==x) return e[son[p][0]].siz+1;
        if (e[p].va>x) return rk(son[p][0],x);
        //x在左子树中 
        if (e[p].va<x) return e[son[p][0]].siz+e[p].num+rk(son[p][1],x);
        //x在右子树中,排名先加上左子树大小和当前位置次数 
    }
    int find(int p,int x)
    {
        if (!p) return 0;
        if (e[son[p][0]].siz>=x) return find(son[p][0],x);
        //rk小于左子树大小,去左子树中找答案 
        else if (e[son[p][0]].siz+e[p].num<x) return find(son[p][1],x-e[son[p][0]].siz-e[p].num);
        //rk大于左子树大小和当前位置次数的和,去右子树中找答案 
        else return e[p].va;
    }
    int pre(int p,int x)
    {
        if (!p) return -inf;
        if (e[p].va>=x) return pre(son[p][0],x);
        //当前值大于等于x,去左子树里找先驱 
        else return max(e[p].va,pre(son[p][1],x));
        //当前值小于x,去右子树里找先驱,并与当前值比较得出答案 
    }
    int suc(int p,int x)
    {
        if (!p) return inf;
        if (e[p].va<=x) return suc(son[p][1],x);
        else return min(e[p].va,suc(son[p][0],x));
    }
    int main()
    {
        int n,op,x;
        scanf("%d",&n);
        while (n--)
        {
            scanf("%d%d",&op,&x);
            if (op==1) ins(rt,x);
            else if (op==2) del(rt,x);
            else if (op==3) printf("%d
    ",rk(rt,x)); 
            else if (op==4) printf("%d
    ",find(rt,x)); 
            else if (op==5) printf("%d
    ",pre(rt,x)); 
            else if (op==6) printf("%d
    ",suc(rt,x)); 
        }
        return 0;
    }
  • 相关阅读:
    idea开发工具关于svn上代码的颜色
    写一个Request包装类ExternalApiHttpServletRequestWrapper(外部接口请求使用用于解密)
    什么情况下,需要用事务?
    SpringBoot 2.1.6.RELEASE ->SpringCloudAlibaba
    oracle查看锁表进程,杀掉锁表进程
    JavaScript 闭包
    萤石云定时更新 accessToken
    Ubuntu Linux的DevExpressReport无法显示报表(.net core)
    Vue在IE下打开空白解决方案
    DFT scan chain 介绍
  • 原文地址:https://www.cnblogs.com/lsykk/p/13447484.html
Copyright © 2020-2023  润新知