平衡树

Binary Index Tree

struct BinaryIndexTree
{
    const static int __=4e5+5;

    ll a[__];int c[__],idx,siz;

    BinaryIndexTree() {clear();}

    void push_back(ll x){a[++idx]=x;}

    int size() {return siz;}

    void build()
    {
        sort(a+1,a+1+idx);
        idx=unique(a+1,a+1+idx)-a-1;
    }

    int get(ll x)
    {
        return lower_bound(a+1,a+1+idx,x)-a;
    }

    void insert(ll x)
    {
        ++siz;
        for(int i=get(x);i<=idx;i+=i&-i)
            ++c[i];
    }

    void erase(ll x)
    {
        --siz;
        for(int i=get(x);i<=idx;i+=i&-i)
            --c[i];
    }

    int sum(int p)
    {
        int res=0;
        for(int i=p;i;i-=i&-i)
            res+=c[i];
        return res;
    }

    //x数的排名
    int rank(ll x)
    {
        int res=1;
        for(int i=get(x)-1;i;i-=i&-i)
            res+=c[i];
        return res;
    }

    //第x个数
    ll operator[](int x)
    {
        int p=idx;
        for(int l=1,r=idx;l<=r;)
        {
            int mid=(l+r)>>1,s=0;
            if(sum(mid)>=x)
                p=mid,r=mid-1;
            else l=mid+1;
        }
        return a[p];
    }

    //>x的最小数
    ll greater(ll x)
    {
        int p=idx,l=get(x);
        for(int y=sum(l++),r=idx;l<=r;)
        {
            int mid=(l+r)>>1;
            if(sum(mid)>y)
                p=mid,r=mid-1;
            else l=mid+1;
        }
        return a[p];
    }

    //<x的最大数
    ll less(ll x)
    {
        int p=1,r=get(x)-1;
        for(int y=sum(r),l=1;l<=r;)
        {
            int mid=(l+r)>>1;
            if(sum(mid-1)<y)
                p=mid,l=mid+1;
            else r=mid-1;
        }
        return a[p];
    }

    //>x的数的个数
    int upper(ll x){return siz-sum(get(x));}

    //<x的数的个数
    int lower(ll x){return sum(get(x)-1);}
    void clear() {idx=siz=0;mem(c,0);}
}bit;

AVL

struct AVL
{
    #define fa(x) t[x].nex[0]
    #define ls(x) t[x].nex[1]
    #define rs(x) t[x].nex[2]

    const static int __=1e5+5;

    struct node
    {
        int val;
        int nex[3],cont,siz,h;

        void set(int pre,int v)
        {
            nex[0]=pre,val=v;
        }
        void clear()
        {
            cont=siz=h=1;
            mem(nex,0);
        }
    }t[__];

    int root;

    void pushup(int x)
    {
        t[x].siz=t[x].cont+t[ls(x)].siz+t[rs(x)].siz;
        t[x].h=max(t[ls(x)].h,t[rs(x)].h)+1;
    }

    struct memory
    {
        static const int __=1e5+5;
        int idx,trash[__];

        int get()
        {
            if(trash[0])return trash[trash[0]--];
            return ++idx;
        }

        void del(int x){trash[++trash[0]]=x;}

        void clear(){idx=trash[0]=0;}
    }M;

    AVL() {clear();}

    void rotate(int x)
    {
        int f=fa(x),k=(x==ls(f))?1:2;
        if(fa(f))
            t[fa(f)].nex[f==ls(fa(f))?1:2]=x;
        else root=x;
        t[f].nex[k]=t[x].nex[3-k];
        t[x].nex[3-k]=f;
        fa(x)=fa(f),fa(f)=x;
        if(t[f].nex[k])fa(t[f].nex[k])=f;
        pushup(f),pushup(x);
    }

    void up(int x)
    {
        for(;x;x=fa(x))
        {
            pushup(x);
            int dh=t[ls(x)].h-t[rs(x)].h;
            if(dh<=-2)
            {
                x=rs(x);
                if(t[ls(x)].h<=t[rs(x)].h)rotate(x);
                else x=ls(x),rotate(x),rotate(x);
            }
            if(dh>=2)
            {
                x=ls(x);
                if(t[ls(x)].h>=t[rs(x)].h)rotate(x);
                else x=rs(x),rotate(x),rotate(x);
            }
        }
    }

    void insert(int v)
    {
        int x=root,y=0;
        while(x && t[x].val!=v)
            if(v<t[y=x].val)x=ls(x);
            else x=rs(x);
        if(x)++t[x].cont;
        else
        {
            x=M.get();
            t[x].clear();
            t[x].set(y,v);
            if(!y)root=x;
            else if(v<t[y].val)ls(y)=x;
            else rs(y)=x;
        }
        up(x);
    }

    void erase(int v)
    {
        int x=root;
        while(x && t[x].val!=v)
            if(v<t[x].val)x=ls(x);
            else x=rs(x);
        if(!x)return;
        --t[x].cont;
        if(!t[x].cont)
        {
loop:
            int k=(x==ls(fa(x)))?1:2;
            if(!ls(x) || !rs(x))
            {
                int y=ls(x)?ls(x):rs(x);
                if(x==root)root=y;
                else t[fa(x)].nex[k]=y;
                fa(y)=fa(x);
            }
            else
            {
                int y=x;
                for(x=ls(x);rs(x);x=rs(x));
                t[y].val=t[x].val;
                t[y].cont=t[x].cont;
                goto loop;
            }
            M.del(x),x=fa(x);
        }
        up(x);
    }

    void clear()
    {
        root=0;
        M.clear();
    }
}T;

Splay

struct Splay
{
    #define fa(x) t[x].nex[0]
    #define ls(x) t[x].nex[1]
    #define rs(x) t[x].nex[2]

    const static int __=1e5+5;

    struct node
    {
        int val;
        int nex[3],cont,siz;

        void set(int pre,int v)
        {
            nex[0]=pre,val=v;
        }
        void clear()
        {
            cont=siz=1;
            mem(nex,0);
        }
    }t[__];

    int root;

    void pushup(int x)
    {
        t[x].siz=t[x].cont+t[ls(x)].siz+t[rs(x)].siz;
    }

    struct memory
    {
        static const int __=1e5+5;
        int idx,trash[__];

        int get()
        {
            if(trash[0])return trash[trash[0]--];
            return ++idx;
        }

        void del(int x){trash[++trash[0]]=x;}

        void clear(){idx=trash[0]=0;}
    }M;

    Splay() {clear();}

    void rotate(int x)
    {
        int f=fa(x),k=(x==ls(f))?1:2;
        if(fa(f))
            t[fa(f)].nex[f==ls(fa(f))?1:2]=x;
        else root=x;
        t[f].nex[k]=t[x].nex[3-k];
        t[x].nex[3-k]=f;
        fa(x)=fa(f),fa(f)=x;
        if(t[f].nex[k])fa(t[f].nex[k])=f;
        pushup(f),pushup(x);
    }

    void splay(int x,int y=0)
    {
        while(fa(x)!=y)
        {
            int f=fa(x),ff=fa(f);
            if(ff==y)rotate(x);
            else
                if((x==ls(f))==(f==ls(ff)))
                    rotate(f),rotate(x);
                else rotate(x),rotate(x);
        }
    }

    void insert(int v)
    {
        int x=root,y=0;
        while(x && t[x].val!=v)
            if(v<t[y=x].val)x=ls(x);
            else x=rs(x);
        if(x)++t[x].cont;
        else
        {
            x=M.get();
            t[x].clear();
            t[x].set(y,v);
            if(!y)root=x;
            else if(v<t[y].val)ls(y)=x;
            else rs(y)=x;
        }
        splay(x);
    }

    void erase(int v)
    {
        int x=root,y=0;
        while(x && t[x].val!=v)
            if(v<t[y=x].val)x=ls(x);
            else x=rs(x);
        if(!x){splay(y);return;}
        splay(x);
        --t[x].cont;
        if(!t[x].cont)
        {
            if(!ls(x) || !rs(x))
            {
                root=ls(x)?ls(x):rs(x);
                fa(root)=0;
            }
            else
            {
                int y=rs(x);
                root=ls(x),fa(ls(x))=0;
                M.del(x);
                for(x=root;rs(x);x=rs(x));
                splay(x);
                rs(x)=y,fa(y)=x;
                pushup(x);
            }
        }
    }

    void clear()
    {
        root=0;
        M.clear();
    }
}T;

Treap

struct Treap
{
    #define fa(x) t[x].nex[0]
    #define ls(x) t[x].nex[1]
    #define rs(x) t[x].nex[2]

    const static int __=1e5+5;

    struct node
    {
        int val,key;
        int nex[3],cont,siz;

        void set(int pre,int v)
        {
            nex[0]=pre,val=v;
        }
        void clear()
        {
            key=rand();
            cont=siz=1;
            mem(nex,0);
        }
    }t[__];

    int root;

    void pushup(int x)
    {
        t[x].siz=t[x].cont+t[ls(x)].siz+t[rs(x)].siz;
    }

    struct memory
    {
        static const int __=1e5+5;
        int idx,trash[__];

        int get()
        {
            if(trash[0])return trash[trash[0]--];
            return ++idx;
        }

        void del(int x){trash[++trash[0]]=x;}

        void clear(){idx=trash[0]=0;}
    }M;

    Treap() {srand(time(0));clear();}

    void rotate(int x)
    {
        int f=fa(x),k=(x==ls(f))?1:2;
        if(fa(f))
            t[fa(f)].nex[f==ls(fa(f))?1:2]=x;
        else root=x;
        t[f].nex[k]=t[x].nex[3-k];
        t[x].nex[3-k]=f;
        fa(x)=fa(f),fa(f)=x;
        if(t[f].nex[k])fa(t[f].nex[k])=f;
        pushup(f),pushup(x);
    }

    void up(int x)
    {
        for(;x;x=fa(x))
        {
            pushup(x);
            if(fa(x) && t[x].key<t[fa(x)].key)
                rotate(x);
        }
    }

    void insert(int v)
    {
        int x=root,y=0;
        while(x && t[x].val!=v)
            if(v<t[y=x].val)x=ls(x);
            else x=rs(x);
        if(x)++t[x].cont;
        else
        {
            x=M.get();
            t[x].clear();
            t[x].set(y,v);
            if(!y)root=x;
            else if(v<t[y].val)ls(y)=x;
            else rs(y)=x;
        }
        up(x);
    }

    void erase(int v)
    {
        int x=root;
        while(x && t[x].val!=v)
            if(v<t[x].val)x=ls(x);
            else x=rs(x);
        if(!x)return;
        --t[x].cont;
        if(!t[x].cont)
        {
loop:
            int k=(x==ls(fa(x)))?1:2;
            if(!ls(x) || !rs(x))
            {
                int y=ls(x)?ls(x):rs(x);
                if(x==root)root=y;
                else t[fa(x)].nex[k]=y;
                fa(y)=fa(x);
            }
            else
            {
                int y=x;
                for(x=ls(x);rs(x);x=rs(x));
                t[y].val=t[x].val;
                t[y].cont=t[x].cont;
                goto loop;
            }
            M.del(x),x=fa(x);
        }
        up(x);
    }

    void clear()
    {
        root=0;
        M.clear();
    }
}T;

Scapegoat Tree

struct ScapegoatTree
{
    #define fa(x) t[x].nex[0]
    #define ls(x) t[x].nex[1]
    #define rs(x) t[x].nex[2]

    const static int __=1e5+5;
    constexpr static double alp=0.75;
    struct node
    {
        int val;
        int nex[3],cont,siz,num;

        void set(int pre,int v,int c)
        {
            nex[0]=pre,val=v,cont=c;
        }
        void clear()
        {
            cont=siz=num=1;
            mem(nex,0);
        }
    }t[__];

    int root,c[__],cont[__];

    void pushup(int x)
    {
        t[x].num=1+t[ls(x)].num+t[rs(x)].num;
        t[x].siz=t[x].cont+t[ls(x)].siz+t[rs(x)].siz;
    }

    struct memory
    {
        static const int __=1e5+5;
        int idx,trash[__];

        int get()
        {
            if(trash[0])return trash[trash[0]--];
            return ++idx;
        }

        void del(int x){trash[++trash[0]]=x;}

        void clear(){idx=trash[0]=0;}
    }M;

    ScapegoatTree() {clear();}

    void dfs(int x)
    {
        if(ls(x))dfs(ls(x));
        c[++c[0]]=t[x].val;
        cont[c[0]]=t[x].cont;
        M.del(x);
        if(rs(x))dfs(rs(x));
    }

    int build(int f,int l,int r)
    {
        if(l>r)return 0;
        int x=M.get(),m=(l+r)>>1;
        t[x].clear();
        t[x].set(f,c[m],cont[m]);
        ls(x)=build(x,l,m-1);
        rs(x)=build(x,m+1,r);
        pushup(x);
        return x;
    }

    void rebuild(int x)
    {
        //pf("rebuild %d\n",t[x].val);
        int f=fa(x);
        c[0]=0,dfs(x);
        int y=build(f,1,c[0]);
        if(!f)root=y;
        else t[f].nex[(x==ls(f))?1:2]=y;
    }

    bool check(int x)
    {
        double k=t[x].num*alp;
        if(t[ls(x)].num>k || t[rs(x)].num>k)
            return true;
        return false;
    }

    void up(int x)
    {
        int y=0;
        for(;x;x=fa(x))
        {
            pushup(x);
            if(check(x))y=x;
        }
        if(y)rebuild(y);
    }

    void insert(int v)
    {
        int x=root,y=0;
        while(x && t[x].val!=v)
            if(v<t[y=x].val)x=ls(x);
            else x=rs(x);
        if(x)++t[x].cont;
        else
        {
            x=M.get();
            t[x].clear();
            t[x].set(y,v,1);
            if(!y)root=x;
            else if(v<t[y].val)ls(y)=x;
            else rs(y)=x;
        }
        up(x);
    }

    void erase(int v)
    {
        int x=root;
        while(x && t[x].val!=v)
            if(v<t[x].val)x=ls(x);
            else x=rs(x);
        if(!x)return;
        --t[x].cont;
        if(!t[x].cont)
        {
loop:
            int k=(x==ls(fa(x)))?1:2;
            if(!ls(x) || !rs(x))
            {
                int y=ls(x)?ls(x):rs(x);
                if(x==root)root=y;
                else t[fa(x)].nex[k]=y;
                fa(y)=fa(x);
            }
            else
            {
                int y=x;
                for(x=ls(x);rs(x);x=rs(x));
                t[y].val=t[x].val;
                t[y].cont=t[x].cont;
                goto loop;
            }
            M.del(x),x=fa(x);
        }
        up(x);
    }

    void clear()
    {
        root=0;
        M.clear();
    }
}T;

Treap(without rotate)

struct Treap
{
    #define fa(x) t[x].nex[0]
    #define ls(x) t[x].nex[1]
    #define rs(x) t[x].nex[2]

    const static int __=1e5+5;

    struct node
    {
        int val,key;
        int nex[3],cont,siz;

        void clear()
        {
            key=rand();
            cont=siz=1;
            mem(nex,0);
        }
    }t[__];

    int root;

    void pushup(int x)
   {
        t[x].siz=t[x].cont+t[ls(x)].siz+t[rs(x)].siz;
    }

    struct memory
    {
        static const int __=1e5+5;
        int idx,trash[__];

        int get()
        {
            if(trash[0])return trash[trash[0]--];
            return ++idx;
        }

        void del(int x){trash[++trash[0]]=x;}

        void clear(){idx=trash[0]=0;}
    }M;

    Treap() {srand(time(0));clear();}

    void up(int x)
    {
        for(;x;x=fa(x))pushup(x);
    }

    int find(int v)
    {
        int x=root;
        while(x && t[x].val!=v)
            if(v<t[x].val)x=ls(x);
            else x=rs(x);
        return x;
    }

    void insert(int v)
    {
        int x=find(v);
        if(x){++t[x].cont;up(x);return;}
        pii y=split(root,v);
        t[x=M.get()].clear();
        t[x].val=v;
        root=merge(merge(y.fi,x),y.se);
    }

    void erase(int v)
    {
        int x=find(v);
        if(!x)return;
        if(--t[x].cont){up(x);return;}
        pii y=split(root,v-1);
        pii z=split(y.se,v);
        root=merge(y.fi,z.se);
    }

    pii split(int x,int v)
    {
        int rt[3]={0},now[3]={0};
        while(x)
        {
            int k=(t[x].val<=v)?1:2;
            if(!rt[k])rt[k]=x;
            else fa(t[now[k]].nex[3-k]=x)=now[k];
            now[k]=x,x=t[x].nex[3-k];
        }
        rs(now[1])=0,up(now[1]);
        ls(now[2])=0,up(now[2]);
        return mp(rt[1],rt[2]);
    }

    int merge(int x,int y)
    {
        if(!x || !y)return x?x:y;
        int rt[3]={0,x,y},z=0,d=0;
        while(rt[1] && rt[2])
        {
            int k=(t[rt[1]].key<=t[rt[2]].key)?1:2;
            if(!rt[1] || !rt[2])k=(rt[1]?1:2);
            if(!rt[0])rt[0]=rt[k];
            else fa(t[z].nex[d]=rt[k])=z;
            z=rt[k],rt[k]=t[rt[k]].nex[d=3-k];
        }
        fa(t[z].nex[d]=rt[1]?rt[1]:rt[2])=z;
        up(z);
        return rt[0];
    }

    void clear()
    {
        root=0;
        M.clear();
    }
}T;
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,233评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,013评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,030评论 0 241
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,827评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,221评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,542评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,814评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,513评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,225评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,497评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,998评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,342评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,986评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,055评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,812评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,560评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,461评论 2 266

推荐阅读更多精彩内容