zoukankan      html  css  js  c++  java
  • 替罪羊树学习总结

    替罪羊树学习总结ScapeGoat Tree

    暴力即优雅——替罪羊树

    学习链接
    各种不同平衡树的算法其本质上的区别在于通过不同的方式维护树的形态,保证每次操作的时间复杂度为(log)

    替罪羊树的核心思想是暴力重构,设定一个参数(ain[0.5,1))其实取到0.5会T飞,对于每颗子树满足(son1/son2.size<a*tree.size)

    bool bad(int k)
    {
        int k1=t[k].son[0],k2=t[k].son[1];
        return (double)max(t[k1].s,t[k2].s)>=(double)t[k].s*alpha;
    }
    

    变量解释

    double alpha=0.75;//平衡因子
    int s[100010];//重构数组
    struct node{
        int son[2],v,die,s;//两个儿子,权值,是否被删除,子树大小
    }t[100010];
    

    重构

    void dfs(int k)
    {
        if(!k) return;
        dfs(t[k].son[0]);if(!t[k].die)s[++top]=k;dfs(t[k].son[1]);
    }
    void build(int &k,int l,int r)
    {
        if(l>r)return;int mid=(l+r)/2;k=s[mid];
        if(l==r)
        {
            t[k].s=1;t[k].son[0]=t[k].son[1]=t[k].die=0;return;
        }
        if(l<mid) build(t[k].son[0],l,mid-1);else t[k].son[0]=0;
        if(r>mid) build(t[k].son[1],mid+1,r);else t[k].son[1]=0;
        t[k].s=t[t[k].son[0]].s+t[t[k].son[1]].s+1;return;
    }
    void rebuild(int &k)
    {
        top=0;dfs(k);if(top)build(k,1,top);
    }
    

    插入操作

    插入操作与普通BST基本无区别,但是每次插入完需要判断是否需要重构,找到深度最浅的需要重构的点进行重构。

    void insert(int &k,int v)
    {
        if(!k)
        {
            k=++cnt;t[k].v=v;t[k].s=1;return;
        }
        if(v<=t[k].v) insert(t[k].son[0],v);
        else insert(t[k].son[1],v);
        int k1=t[k].son[0],k2=t[k].son[1];
        t[k].s=t[k1].s+t[k2].s+exist(k);
        if(!bad(k))
        {
            if(need)
            {
                if(need==t[k].son[0]) rebuild(t[k].son[0]);
                else rebuild(t[k].son[1]);
            }
            need=0;
        }
        else need=k;
    }
    

    删除操作

    删除操作并不需要真正删除节点,只需要给这个节点打上标记,在之后处理的时候忽略掉就可以啦

    void delet(int k,int v)
    {
        if(!k) return;
        int k1=t[k].son[0],k2=t[k].son[1];
        if(!t[k].die&&t[k1].s+1==v){t[k].die=1;t[k].s--;return;}
        if(t[k1].s>=v) delet(k1,v);
        else delet(k2,v-t[k1].s-exist(k));
        t[k].s=t[k1].s+t[k2].s+exist(k);
        if(!bad(k))
        {
            if(need)
            {
                if(need==t[k].son[0]) rebuild(t[k].son[0]);
                else rebuild(t[k].son[1]);
            }
            need=0;
        }
        else need=k;
    }
    

    查询操作

    查询操作与普通BST操作没有区别。

    例题:

    [模板]普通平衡树
    [NOI2004]郁闷的出纳员

  • 相关阅读:
    Web前端工程师技能列表
    CSS框架的相关汇总(CSS Frameworks)
    一个有趣的发现
    (转丁学)Firefox2的一个bug和脑子进了水的IE
    深入语义:列表Tag(ul/ol)和表格Tag(table)的抉择
    css命名简单框架
    腾讯的三栏布局考题
    土豆网前端概况
    伪绝对定位(译)
    右下角浮动广告代码DEMO
  • 原文地址:https://www.cnblogs.com/lsgjcya/p/9349204.html
Copyright © 2011-2022 走看看