各种平衡树板子

Posted passione-123456

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了各种平衡树板子相关的知识,希望对你有一定的参考价值。

Splay

技术图片
#include <bits/stdc++.h>
#define root e[0].son[1]
using namespace std;
int read() {
    int re = 0, f = 1;
    char ch = getchar();
    while (ch < 0 || ch > 9) {if (ch == -) f = -f; ch = getchar();}
    while (0 <= ch && ch <= 9) {re = re * 10  + ch - 0; ch = getchar();}
    return re * f;
}
const int N = 1e5 + 3;
const int INF = 1e7 + 3;
int n, cnt;
struct node{
    int v,recy,sum;//Ȩֵ Öظ´¸öÊý ×ÓÊ÷×ܸöÊý 
    int fa,son[2];//µù ¶ù×Ó
}e[N];
void update(int x){//¸üдóС 
    e[x].sum=e[e[x].son[0]].sum+e[e[x].son[1]].sum+e[x].recy;
}
bool identify(int x){//È·¶¨¸¸×Ó¹Øϵ 
    return e[e[x].fa].son[0]==x?0:1;
}
void connect(int x,int fa,int son){//ÈÏÇ× 
    e[x].fa=fa,e[fa].son[son]=x;
}
void rotate(int x){//Ðýת 
    int y=e[x].fa,z=e[y].fa;
    int zson=identify(y),yson=identify(x),xson=e[x].son[yson^1];
    connect(xson,y,yson);connect(y,x,yson^1);connect(x,z,zson);
    update(y);update(x);
    return ;
}
void splay(int x,int to){//Òƶ¯xµ½toµÄλÖà 
    int tofa=e[to].fa;
    while(tofa!=e[x].fa){
        int fa=e[x].fa;
        int gfa=e[fa].fa;
        if(gfa!=tofa){
            if(identify(x)!=identify(fa))rotate(x);
            else rotate(fa);
        }
        rotate(x);
    }
    if(to==root)root=x;
}
int newpoint(int v,int fa){//½¨Ðµã 
    e[++cnt].fa=fa;
    e[cnt].v=v;
    e[cnt].sum=e[cnt].recy=1;
    return cnt;
}
void Insert(int v){//²åÈëȨֵΪvµÄµã 
    int now=root;
    if(!root){root=newpoint(v,0);}
    else{
        while(1){
            e[now].sum++;
            if(e[now].v==v){e[now].recy++;splay(now,root);return;}
            int next=e[now].v<v?1:0;
            if(!e[now].son[next]){
                e[now].son[next]=newpoint(v,now);splay(cnt,root);return;
            }
            now=e[now].son[next];
        }
    }
}
int find(int v){//²éѯȨֵΪvµÄµãÔÚµÄλÖà 
    int now=root;
    while(1){
        if(e[now].v==v){splay(now,root);return now;}
        int next=e[now].v<v?1:0;
        if(!e[now].son[next])return 0;
        now=e[now].son[next];
    }
}
void delet(int v){//ɾ³ýȨֵΪvµÄµã 
    int now=find(v);
    if(!now)return;
    if(e[now].recy>1){e[now].recy--;e[now].sum--;}
    else{
        if(!e[now].son[0]&&!e[now].son[1]){root=0;}
        else if(!e[now].son[0]){root=e[now].son[1];e[root].fa=0;}
        else{
            int lef=e[now].son[0];
            while(e[lef].son[1])lef=e[lef].son[1];
            splay(lef,e[now].son[0]);
            connect(e[now].son[1],lef,1);
            connect(lef,0,1);
            update(lef);
        }
    }
}
int _rank(int v){//²éѯȨֵΪvµÄµãµÄÅÅÃû 
    return e[e[find(v)].son[0]].sum+1;
}
int _kth(int k){//²éѯµÚxÃûµÄȨֵ 
    int now=root;
    while(1){
        int used=e[now].sum-e[e[now].son[1]].sum;
        if(e[e[now].son[0]].sum<k&&k<=used){splay(now,root);return e[now].v;}
        if(k<used){now=e[now].son[0];} 
        else{k-=used;now=e[now].son[1];}
    }
}
int lower(int x){//Ç°Çý 
    int now=root,val=-0x3f3f3f3f;
    while(now){
        if(e[now].v<x)val=max(val,e[now].v);
        if(e[now].v<x)now=e[now].son[1];
        else now=e[now].son[0];    
    }
    return val;
}
int upper(int x){//ºó¼Ì 
    int now=root,val=0x3f3f3f3f;
    while(now){
        if(e[now].v>x)val=min(val,e[now].v);
        if(e[now].v<=x)now=e[now].son[1];
        else now=e[now].son[0];    
    }
    return val;
}
int main () {
    n = read();
    while (n--) {
        int opt = read();
        int x = read();
        if (opt == 1) Insert(x);
        else if (opt == 2) delet(x);
        else if (opt == 3) printf("%d
", _rank(x));
        else if (opt == 4) printf("%d
", _kth(x));
        else if (opt == 5) printf("%d
", lower(x));
        else if (opt == 6) printf("%d
", upper(x));
    }
    return 0;
}
Splay

Treap

技术图片
#include<bits/stdc++.h>
using namespace std;
const int N=300010;
int n,cnt,root;
struct node{
    int v,recy,sum;//Ȩֵ Öظ´¸öÊý ×ÓÊ÷×ܸöÊý 
    int fa,son[2];//µù ¶ù×Ó
    int rk;//Ëæ»úÖµ 
}e[N];
void update(int x){//¸üдóС 
    e[x].sum=e[e[x].son[0]].sum+e[e[x].son[1]].sum+e[x].recy;
}
void rotate(int &x,int next){//Ðýת 
    int y=e[x].son[next^1];
    e[x].son[next^1]=e[y].son[next];e[y].son[next]=x;
    update(x);update(y);x=y;
}
int newpoint(int v){//½¨Ðµã 
    e[++cnt].v=v;
    e[cnt].sum=e[cnt].recy=1;
    e[cnt].rk=rand();
    return cnt;
}
void Insert(int &x,int v){//²åÈëȨֵΪvµÄµã
    if(!x){x=newpoint(v);return;}
    if(e[x].v==v){e[x].recy++;e[x].sum++;return;}
    int next=e[x].v<v?1:0;
    Insert(e[x].son[next],v);
    if(e[x].rk<e[e[x].son[next]].rk)rotate(x,next^1);
    update(x);
}
void delet(int &x,int v){//ɾ³ýȨֵΪvµÄµã 
    if(!x)return;
    if(v<e[x].v)delet(e[x].son[0],v);
    else if(v>e[x].v)delet(e[x].son[1],v);
    else {
        if(!e[x].son[0]&&!e[x].son[1]){
            e[x].recy--;
            e[x].sum--;
            if(!e[x].recy)x=0;
        }else if(e[x].son[0]&&e[x].son[1]){
            int next=e[e[x].son[0]].rk>e[e[x].son[1]].rk?1:0;
            rotate(x,next);
            delet(e[x].son[next],v);
        }else{
            int next=!e[x].son[1];
            rotate(x,next);
            delet(e[x].son[next],v);
        }
    }
    update(x);
}
int _rank(int x,int v){//²éѯȨֵΪvµÄµãµÄÅÅÃû 
    if(!x)return 0;
    else if(e[x].v<v)return e[e[x].son[0]].sum+e[x].recy+_rank(e[x].son[1],v);
    else if(e[x].v>v)return _rank(e[x].son[0],v);
    else return e[e[x].son[0]].sum+1;
}
int _kth(int x,int k){//²éѯµÚkÃûµÄȨֵ 
    if(!x)return 0;
    else if(e[e[x].son[0]].sum>=k)return _kth(e[x].son[0],k);
    else if(e[e[x].son[0]].sum+e[x].recy<k){
        return _kth(e[x].son[1],k-e[e[x].son[0]].sum-e[x].recy);
    }
    else return e[x].v;
}
int lower(int x,int v){//Ç°Çý 
    if(!x)return -0x3f3f3f3f;
    if(e[x].v>=v)return lower(e[x].son[0],v);
    else return max(e[x].v,lower(e[x].son[1],v));
}
int upper(int x,int v){//ºó¼Ì 
    if(!x)return 0x3f3f3f3f;
    if(e[x].v<=v)return upper(e[x].son[1],v);
    else return min(e[x].v,upper(e[x].son[0],v));
}
int main(){
    scanf("%d",&n);
    for (int i=0;i<n;++i)
    {
        int opt,x;
        scanf("%d%d",&opt,&x);
        if (opt==1) Insert(root,x);
        else if (opt==2) delet(root,x);
        else if (opt==3) printf("%d
",_rank(root,x));
        else if (opt==4) printf("%d
",_kth(root,x));
        else if (opt==5) printf("%d
",lower(root,x));
        else if (opt==6) printf("%d
",upper(root,x));
    }
    return 0;
}
Treap

以上是关于各种平衡树板子的主要内容,如果未能解决你的问题,请参考以下文章

替罪羊树(重量平衡树)总结及板子

几个平衡树板子

[bzoj] 3224 Tyvj 1728 普通平衡树 || 平衡树板子题

平衡树板子qaq

3224: Tyvj 1728 普通平衡树(新板子)

P3391 模板文艺平衡树(Splay)新板子