平衡树代码总结

这里给出博主的几种平衡树模板代码

vector

代码:

// luogu-judger-enable-o2
#include<bits/stdc++.h>

#define rd(x) x=read()

using namespace std;

int n;
vector<int>v;

inline int read()
{
    int f=1,x=0;char s=getchar();
    while(s<‘0‘||s>‘9‘){if(s==‘-‘)f=-1;s=getchar();}
    while(s>=‘0‘&&s<=‘9‘){x=x*10+s-‘0‘;s=getchar();}
    return x*f;
}

int main()
{
    rd(n);
    for(int i=1;i<=n;i++)
    {
        int opt,x;
        rd(opt),rd(x);
        if(opt==1)v.insert(upper_bound(v.begin(),v.end(),x),x);
        else if(opt==2)v.erase(lower_bound(v.begin(),v.end(),x));
        else if(opt==3)printf("%d\n",lower_bound(v.begin(),v.end(),x)-v.begin()+1);
        else if(opt==4)printf("%d\n",v[x-1]);
        else if(opt==5)printf("%d\n",*--lower_bound(v.begin(),v.end(),x));
        else if(opt==6)printf("%d\n",*upper_bound(v.begin(),v.end(),x));
    }
    return 0;
}

Treap:

// luogu-judger-enable-o2
#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include<bits/stdc++.h>

#define rd(x) x=read()
#define N 100005
#define inf (1<<30) 

using namespace std;

inline int read()
{
    int f=1,x=0;char s=getchar();
    while(s<‘0‘||s>‘9‘){if(s==‘-‘)f=-1;s=getchar();}
    while(s>=‘0‘&&s<=‘9‘){x=x*10+s-‘0‘;s=getchar();}
    return x*f;
}

int q;
int ncnt,root;
struct T{
    int s,v,cnt,rnd,ch[2];
}t[N];

void pushup(int rt){t[rt].s=t[t[rt].ch[0]].s+t[t[rt].ch[1]].s+t[rt].cnt;}

void rotate(int &rt,int d)
{
    int k=t[rt].ch[d^1];
    t[rt].ch[d^1]=t[k].ch[d];
    t[k].ch[d]=rt;
    pushup(rt),pushup(k);
    rt=k;
}

void ins(int &rt,int x)
{
    if(!rt)
    {
        rt=++ncnt,t[rt].s=t[rt].cnt=1,t[rt].v=x,t[rt].rnd=rand();
        return ;
    }
    if(t[rt].v==x){t[rt].cnt++,t[rt].s++;return ;}
    int d=(x>t[rt].v);
    ins(t[rt].ch[d],x);
    if(t[rt].rnd<t[t[rt].ch[d]].rnd)rotate(rt,d^1);
    pushup(rt);
}

void del(int &rt,int x)
{
    if(!rt)return;
    if(x<t[rt].v)del(t[rt].ch[0],x);
    else if(x>t[rt].v)del(t[rt].ch[1],x);
    else
        if(t[rt].ch[0])
            if(t[rt].ch[1])
            {
                int d=(t[t[rt].ch[0]].rnd>t[t[rt].ch[1]].rnd);
                rotate(rt,d);
                del(t[rt].ch[d],x);
            }
            else
            {
                rotate(rt,1);
                del(t[rt].ch[1],x);
            }
        else
            if(t[rt].ch[1])
            {
                rotate(rt,0);
                del(t[rt].ch[0],x);
            }
            else
            {
                t[rt].cnt--,t[rt].s--;
                if(!t[rt].cnt)rt=0;
            }
    pushup(rt);
}

int rank(int rt,int x)
{
    if(!rt)return 0;
    if(t[rt].v==x)return t[t[rt].ch[0]].s+1;
    else if(t[rt].v<x)return t[t[rt].ch[0]].s+t[rt].cnt+rank(t[rt].ch[1],x);
    else return rank(t[rt].ch[0],x);
}

int find(int rt,int x)
{
    if(!rt)return 0;
    if(t[t[rt].ch[0]].s>=x)return find(t[rt].ch[0],x);
    else if(t[t[rt].ch[0]].s+t[rt].cnt<x)return find(t[rt].ch[1],x-t[rt].cnt-t[t[rt].ch[0]].s);
    else return t[rt].v;
}

int pre(int rt,int x)
{
    if(!rt)return -inf;
    if(t[rt].v>=x)return pre(t[rt].ch[0],x);
    else return max(t[rt].v,pre(t[rt].ch[1],x));
}

int suc(int rt,int x)
{
    if(!rt)return inf;
    if(t[rt].v<=x)return suc(t[rt].ch[1],x);
    else return min(t[rt].v,suc(t[rt].ch[0],x));
}

int main()
{
    rd(q);
    while(q--)
    {
        int opt,x;
        rd(opt),rd(x);
        if(opt==1)ins(root,x);
        else if(opt==2)del(root,x);
        else if(opt==3)printf("%d\n",rank(root,x));
        else if(opt==4)printf("%d\n",find(root,x));
        else if(opt==5)printf("%d\n",pre(root,x));
        else printf("%d\n",suc(root,x));
    }

    return 0;
}

Splay

// luogu-judger-enable-o2
#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include<iostream>
#include<cstdio>

#define rd(x) x=read()
#define N 100005

using namespace std;

int q;
int ncnt,root;
struct T{
    int s,v,cnt,fa,ch[2];
}t[N];

inline int read()
{
    int f=1,x=0;char s=getchar();
    while(s<‘0‘||s>‘9‘){if(s==‘-‘)f=-1;s=getchar();}
    while(s>=‘0‘&&s<=‘9‘){x=x*10+s-‘0‘;s=getchar();}
    return x*f;
}

int chk(int rt){return t[t[rt].fa].ch[1]==rt;}

int pushup(int rt){return t[rt].s=t[t[rt].ch[0]].s+t[t[rt].ch[1]].s+t[rt].cnt;}

void rotate(int x)
{
    int y=t[x].fa,z=t[y].fa,k=chk(x),w=t[x].ch[k^1];
    t[y].ch[k]=w,t[w].fa=y;
    t[z].ch[chk(y)]=x,t[x].fa=z;
    t[x].ch[k^1]=y,t[y].fa=x;
    pushup(y),pushup(x);
}

void splay(int x,int goal=0)
{
    while(t[x].fa!=goal)
    {
        int y=t[x].fa,z=t[y].fa;
        if(z!=goal)
        {
            if(chk(x)==chk(y))rotate(y);
            else rotate(x);
        }
        rotate(x);
    }
    if(!goal)root=x;
}

void ins(int x)
{
    int rt=root,pos=0;
    while(rt&&t[rt].v!=x)pos=rt,rt=t[rt].ch[x>t[rt].v];
    if(rt)t[rt].cnt++;
    else
    {
        rt=++ncnt;
        if(pos)t[pos].ch[x>t[pos].v]=rt;
        t[rt].ch[0]=t[rt].ch[1]=0;
        t[rt].fa=pos,t[rt].v=x;
        t[rt].cnt=t[rt].s=1;
    }
    splay(rt);
}

void find(int x)
{
    int rt=root;
    while(t[rt].ch[x>t[rt].v]&&t[rt].v!=x)rt=t[rt].ch[x>t[rt].v];
    splay(rt);
}

int rank(int k)
{
    int rt=root;
    while("zth loves msy")
    {
        if(t[rt].ch[0]&&k<=t[t[rt].ch[0]].s)rt=t[rt].ch[0];
        else if(k>t[t[rt].ch[0]].s+t[rt].cnt)k-=t[t[rt].ch[0]].s+t[rt].cnt,rt=t[rt].ch[1];
        else return rt;
    }
}

int pre(int x)
{
    find(x);
    if(t[root].v<x)return root;
    int rt=t[root].ch[0];
    while(t[rt].ch[1])rt=t[rt].ch[1];
    return rt;
}

int suc(int x)
{
    find(x);
    if(t[root].v>x)return root;
    int rt=t[root].ch[1];
    while(t[rt].ch[0])rt=t[rt].ch[0];
    return rt;
}

void del(int x)
{
    int last=pre(x),next=suc(x);
    splay(last),splay(next,last);
    int _del=t[next].ch[0];
    if(t[_del].cnt>1)
    {
        t[_del].cnt--;
        splay(_del);
    }
    else t[next].ch[0]=0;
} 

int main()
{
    rd(q);
    ins(0x3f3f3f3f),ins(0xcfcfcfcf);
    while(q--)
    {
        int opt,x;
        rd(opt),rd(x);
        if(opt==1)ins(x);
        else if(opt==2)del(x);
        else if(opt==3){find(x);printf("%d\n",t[t[root].ch[0]].s);}
        else if(opt==4)printf("%d\n",t[rank(x+1)].v);
        else if(opt==5)printf("%d\n",t[pre(x)].v);
        else printf("%d\n",t[suc(x)].v);
    }

    return 0;
}

替罪羊树

// luogu-judger-enable-o2
#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include<bits/stdc++.h>

#define rd(x) x=read()
#define N 100005

using namespace std;

struct T{
    int s,f,v,d,ch[2];
}t[N];
int ncnt,root,cnt;
int Lrd[N],r[N];
int n;
const double p=0.75;

inline int read()
{
    int f=1,x=0;char s=getchar();
    while(s<‘0‘||s>‘9‘){if(s==‘-‘)f=-1;s=getchar();}
    while(s>=‘0‘&&s<=‘9‘){x=x*10+s-‘0‘;s=getchar();}
    return x*f;
}

void init(int rt)
{
    t[rt].s=t[rt].f=1;
    t[rt].ch[0]=t[rt].ch[1]=0;
}

bool bal(int rt){return (double)t[rt].f*p>(double)max(t[t[rt].ch[0]].f,t[t[rt].ch[1]].f);} 

void lrd(int rt)
{
    if(!rt)return;
    lrd(t[rt].ch[0]);
    if(t[rt].d)Lrd[++cnt]=rt;
    lrd(t[rt].ch[1]);
}

void pushup(int rt)
{
    t[rt].s=t[t[rt].ch[0]].s+t[t[rt].ch[1]].s+1;
    t[rt].f=t[t[rt].ch[0]].f+t[t[rt].ch[1]].f+1;
}

void setup(int &rt,int l,int r)
{
    int mid=(l+r)>>1;
    rt=Lrd[mid];
    if(l==r){init(rt);return;}
    if(l<mid)setup(t[rt].ch[0],l,mid-1);
    else t[rt].ch[0]=0;
    setup(t[rt].ch[1],mid+1,r);
    pushup(rt);
}

void rebuild(int &rt)
{
    cnt=0;
    lrd(rt);
    if(cnt)setup(rt,1,cnt);
    else rt=0;
}

void check(int rt,int v)
{
    int k=(v>t[rt].v);
    while(t[rt].ch[k])
    {
        if(!bal(t[rt].ch[k]))
        {
            rebuild(t[rt].ch[k]);
            return ;
        }
        rt=t[rt].ch[k];
        k=(v>t[rt].v);
    }
}

void ins(int &rt,int x)
{
    if(!rt)
    {
        rt=++ncnt,t[rt].v=x,t[rt].d=1,init(rt);
        return ;
    }
    t[rt].s++,t[rt].f++;
    if(x<=t[rt].v)ins(t[rt].ch[0],x);
    else ins(t[rt].ch[1],x);
}

int rank(int x)
{
    int rk=1,rt=root;
    while(rt)
    {
        if(t[rt].v>=x)rt=t[rt].ch[0];
        else rk+=t[t[rt].ch[0]].f+t[rt].d,rt=t[rt].ch[1];
    }
    return rk;
}

int find(int x)
{
    int rt=root;
    while(rt)
    {
        if(t[rt].d&&t[t[rt].ch[0]].f+1==x)return t[rt].v;
        else if(t[t[rt].ch[0]].f>=x)rt=t[rt].ch[0];
        else x-=t[rt].d+t[t[rt].ch[0]].f,rt=t[rt].ch[1];
    }
}

void del(int &rt,int rk)
{
    if(t[rt].d&&t[t[rt].ch[0]].f+1==rk)
    {
        t[rt].d=0;
        t[rt].f--;
        return ;
    }
    t[rt].f--;
    if(t[t[rt].ch[0]].f+t[rt].d>=rk)del(t[rt].ch[0],rk);
    else del(t[rt].ch[1],rk-t[rt].d-t[t[rt].ch[0]].f);
}

void Del(int x)
{
    del(root,rank(x));
    if((double)t[root].s*p>(double)t[root].f)rebuild(root);
}

int main()
{
    rd(n);
    while(n--)
    {
        int opt,x;
        rd(opt),rd(x);
        if(opt==1)ins(root,x),check(root,x);
        else if(opt==2)Del(x);
        else if(opt==3)printf("%d\n",rank(x));
        else if(opt==4)printf("%d\n",find(x));
        else if(opt==5)printf("%d\n",find(rank(x)-1));
        else printf("%d\n",find(rank(x+1)));
    }

    return 0;
}

FHQ treap

// luogu-judger-enable-o2
#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include<bits/stdc++.h>

#define rd(x) x=read()
#define N 100005

using namespace std;

int n;
int ncnt;
struct T{
    int v,rnd,s,ch[2];
}t[N];

inline int read()
{
    int f=1,x=0;char s=getchar();
    while(s<‘0‘||s>‘9‘){if(s==‘-‘)f=-1;s=getchar();}
    while(s>=‘0‘&&s<=‘9‘){x=x*10+s-‘0‘;s=getchar();}
    return x*f;
}

void update(int rt){t[rt].s=t[t[rt].ch[0]].s+t[t[rt].ch[1]].s+1;}

int NewNode(int v)
{
    t[++ncnt].s=1;
    t[ncnt].v=v;
    t[ncnt].rnd=rand();
    return ncnt;
}

int merge(int x,int y)
{
    if(!x||!y) return x+y;
    if(t[x].rnd<t[y].rnd)
    {
        t[x].ch[1]=merge(t[x].ch[1],y);
        update(x);
        return x;
    }
    else
    {
        t[y].ch[0]=merge(x,t[y].ch[0]);
        update(y);
        return y;
    }
}

void split(int rt,int pos,int &l,int &r)
{
    if(!rt)l=r=0;
    else
    {
        if(t[rt].v<=pos)
        {
            l=rt;
            split(t[rt].ch[1],pos,t[rt].ch[1],r);
        }
        else
        {
            r=rt;
            split(t[rt].ch[0],pos,l,t[rt].ch[0]);
        }
        update(rt);
    }
}

int kth(int rt,int pos)
{
    while(1)
    {
        if(pos<=t[t[rt].ch[0]].s)rt=t[rt].ch[0];
        else if(pos==t[t[rt].ch[0]].s+1) return rt;
        else
        {
            pos-=t[t[rt].ch[0]].s+1;
            rt=t[rt].ch[1];
        }
    }
}

int main()
{
    srand(time(0));
    rd(n);
    int root=0,x,y,z;
    while(n--)
    {
        int opt,a;
        rd(opt),rd(a);
        if(opt==1)
        {
            split(root,a,x,y);
            root=merge(merge(x,NewNode(a)),y);
        }
        else if(opt==2)
        {
            split(root,a,x,z);
            split(x,a-1,x,y);
            y=merge(t[y].ch[0],t[y].ch[1]);
            root=merge(merge(x,y),z);
        }
        else if(opt==3)
        {
            split(root,a-1,x,y);
            printf("%d\n",t[x].s+1);
            root=merge(x,y);
        }
        else if(opt==4)printf("%d\n",t[kth(root,a)].v);
        else if(opt==5)
        {
            split(root,a-1,x,y);
            printf("%d\n",t[kth(x,t[x].s)].v);
            root=merge(x,y);
        }
        else if(opt==6)
        {
            split(root,a,x,y);
            printf("%d\n",t[kth(y,1)].v);
            root=merge(x,y);
        }
    }

    return 0;
}

原文地址:https://www.cnblogs.com/Robin20050901/p/10665195.html

时间: 2024-10-17 06:30:46

平衡树代码总结的相关文章

编程算法 - 判断二叉树是不是平衡树 代码(C)

判断二叉树是不平衡树 代码(C) 本文地址: http://blog.csdn.net/caroline_wendy 题目: 输入一颗二叉树的根结点, 判断该树是不是平衡二叉树. 二叉平衡树: 任意结点的左右子树的深度相差不超过1. 使用后序遍历的方式, 并且保存左右子树的深度, 进行比较. 代码: /* * main.cpp * * Created on: 2014.6.12 * Author: Spike */ /*eclipse cdt, gcc 4.8.1*/ #include <std

编程算法 - 推断二叉树是不是平衡树 代码(C)

推断二叉树是不平衡树 代码(C) 本文地址: http://blog.csdn.net/caroline_wendy 题目: 输入一颗二叉树的根结点, 推断该树是不是平衡二叉树. 二叉平衡树: 随意结点的左右子树的深度相差不超过1. 使用后序遍历的方式, 而且保存左右子树的深度, 进行比較. 代码: /* * main.cpp * * Created on: 2014.6.12 * Author: Spike */ /*eclipse cdt, gcc 4.8.1*/ #include <std

普通平衡树代码。。。Treap

应一些人之邀...发一篇代码 1 #include <iostream> 2 #include <cstdio> 3 #include <cstdlib> 4 #include <cstring> 5 6 using namespace std; 7 struct node 8 { 9 int data; 10 int key; 11 node* ls; 12 node* rs; 13 int size; 14 15 node() 16 { 17 key=r

fhq-Treap 文艺平衡树代码记录

#include<iostream> #include<algorithm> #include<vector> #include<cstdio> #include<string> using namespace std; const int N=1e4+10; int a[N]; int root; int idx; int x,y,z; struct node{ int l,r; int size; int val; int key; int

斜堆,非旋转treap,替罪羊树

一.斜堆 斜堆是一种可以合并的堆 节点信息: struct Node { int v; Node *ch[2]; }; 主要利用merge函数 Node *merge(Node *x, Node *y) { if(!x) return y; if(!y) return x; if(x->v < y->v) swap(x, y); x->ch[1] = merge(x->ch[1], y); return swap(x->ch[0], x->ch[1]), x; }

[您有新的未分配科技点]可,可,可持久化!?------0-1Trie和可持久化Trie普及版讲解

这一次,我们来了解普通Trie树的变种:0-1Trie以及在其基础上产生的可持久化Trie(其实,普通的Trie也可以可持久化,只是不太常见) 先简单介绍一下0-1Trie:一个0-1Trie节点只有两个子节点,分别代表0和1:从根节点开始,第一层代表限制的最高位,依次往下直到最底层,代表二进制第0位. 0-1Trie上的一条链所表示的数字,就是Trie树中的一个数字.0-1Trie除了节点和插入方式与普通的Trie树略有不同之外,其他操作都是和Trie树完全一样的.在维护这个节点插入过的siz

AC日记——[ZJOI2007]报表统计 bzoj 1058

1058 思路: 平衡树的题: 然而我的平衡树写一次炸一次QwQ: 而且各种tle: 所以stl水过: 代码: #include <set> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; #define maxn 1000005 class HeadType { private: int head

luoguP3871 [TJOI2010]中位数

题目链接 luoguP3871 [TJOI2010]中位数 题解 平衡树 代码 #include<vector> #include<cstdio> #include<cstring> #include<algorithm> #define LL long long inline int read() { int x = 0,f = 1;char c = getchar(); while(c < '0'||c > '9'){if(c == '-')

非旋 treap 结构体数组版(无指针)详解,有图有真相

非旋  $treap$ (FHQ treap)的简单入门 前置技能 建议在掌握普通 treap 以及 左偏堆(也就是可并堆)食用本blog 原理 以随机数维护平衡,使树高期望为logn级别, FHQ 不依靠旋转,只有两个核心操作merge(合并)和split(拆分) 所谓随机数维护平衡就是给每个节点一个随机值 key (下文中没有加随机的就代表是真实权值), 然后整棵树中 key 值要满足小(大)根堆的性质(也就是heap), 同时也要满足平衡树(tree)的性质(也就是每个节点左子树内节点真实