普通平衡树 替罪羊树模板

不平衡时暴力重构子树,可以说很少写且跑得很快

//Achen
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<vector>
#include<queue>
#include<ctime>
#include<cmath> 
const int N=100007*20; 
typedef long long LL;
typedef double db;
using namespace std;
int T,o,xx,rt;

namespace RD{
    const int sz=1<<15|1;
    char ch,buf[sz],*l,*r;
    void gechar(char &c) {
        if(l==r) r=(l=buf)+fread(buf,1,sz,stdin);
        c = l==r?EOF:*l++;
    }
    template<typename T> void read(T &x) {
        gechar(ch); x=0; T f=1;
        while(ch!='-'&&(ch<'0'||ch>'9')) gechar(ch);
        if(ch=='-') f=-1,gechar(ch);
        for(;ch>='0'&&ch<='9';gechar(ch)) x=x*10+ch-'0'; x*=f;
    }
}


int tot,ch[N][2],p[N],v[N],sz[N],E[N];
#define lc ch[x][0]
#define rc ch[x][1]

int update(int x) {sz[x]=sz[lc]+sz[rc]+1;}

int bal(int x) {
    return 0.75*sz[x]>=(db)sz[lc]&&0.75*sz[x]>=(db)sz[rc];
} 

int findx(int y) {
    for(int x=rt;x;) {
        if(v[x]==y) return x;
        if(v[x]<y) x=rc;
        else x=lc;
    }
}

void tra(int x){
    if(lc) tra(lc);
    E[++E[0]]=x;
    if(rc) tra(rc);
}

int build(int l,int r) {
    if(l>r) return 0;
    int mid=(l+r)>>1;
    int x=E[mid];
    lc=build(l,mid-1); p[lc]=x;
    rc=build(mid+1,r); p[rc]=x;
    update(x);
    return x;
}

void rebuild(int x) {
    E[0]=0; tra(x);
    int y=p[x],z=build(1,E[0]);
    if(y) ch[y][x==ch[y][1]]=z; p[z]=y;
    if(x==rt) rt=z;
}

int cre(int y) {
    int x=++tot; 
    v[x]=y;
    sz[x]=1;
    return x;
}

void insert(int y) {
    int fa=0,l=1,z=cre(y);
    for(int x=rt;;) {
        if(!x) {
            x=z; p[x]=fa;
            if(fa) ch[fa][l]=x; 
            else rt=x;
            break;
        }
        sz[x]++;
        if(v[x]<y) fa=x,l=1,x=rc;
        else fa=x,l=0,x=lc;
    }
    int tp=0;
    for(int x=z;x;x=p[x]) if(!bal(x)) tp=x;
    if(tp) rebuild(tp);
}

void del(int x) {
    if(lc&&rc) {
        int y=lc;
        while(ch[y][1]) y=ch[y][1];
        v[x]=v[y];
        x=y;
    }
    int son=lc?lc:rc;
    p[son]=p[x]; 
    if(p[x]) ch[p[x]][x==ch[p[x]][1]]=son;
    else rt=son;
    for(int i=p[son];i;i=p[i]) sz[i]--;
}

int rank(int y) {
    int res=1;
    for(int x=rt;x;) {
        if(v[x]<y) res+=sz[lc]+1,x=rc;
        else x=lc;
    }     
    return res;
}

int kth(int y) {
    for(int x=rt;x;) {
        if(sz[lc]+1==y) return v[x];
        if(sz[lc]+1<y) y-=(sz[lc]+1),x=rc;
        else x=lc; 
    }
}

int pre(int y) {
    int res=-1;
    for(int x=rt;x;) {
        if(v[x]<y) res=v[x],x=rc;
        else x=lc;
    }
    return res;
}

int nxt(int y) {
    int res=-1;
    for(int x=rt;x;) {
        if(v[x]>y) res=v[x],x=lc;
        else x=rc;
    }
    return res;
}


int main() {
    RD::read(T);
    while(T--) {
        RD::read(o); RD::read(xx);
        switch(o) {
            case 1:insert(xx);break;
            case 2:del(findx(xx));break;
            case 3:printf("%d\n",rank(xx));break;
            case 4:printf("%d\n",kth(xx));break;
            case 5:printf("%d\n",pre(xx));break;
            case 6:printf("%d\n",nxt(xx));break;
        }
    } 
    return 0;
}
View Code

 

posted @ 2017-12-11 07:12  啊宸  阅读(121)  评论(0编辑  收藏  举报