BZOJ3224: 普通平衡树

——————————————————————————————————————————————————————————————----————

搞了半天的BZOJ美化233333,所以贴了BZOJ的图

oi生涯写过的最长的数据结构吧

压行选手还写了85+line

#include<bits/stdc++.h>
using namespace std;
const int inf=0x7fffffff;
const int bow=101000;
int t,root,tot;
int dat[bow],val[bow],l[bow],r[bow],size[bow],cnt[bow];
void update(int x){size[x]=size[l[x]]+size[r[x]]+cnt[x];}
int cte(int c){val[++tot]=c;dat[tot]=rand();cnt[tot]=size[tot]=1;return tot;}
void build(){cte(-inf);cte(inf);root=1;r[1]=2;update(root);}
void zig(int &p){int q=l[p];l[p]=r[q];r[q]=p;p=q;update(r[p]);update(p);}
void zag(int &p){int q=r[p];r[p]=l[q];l[q]=p;p=q;update(l[p]);update(p);}
void insert(int &p,int c)
{
    if(p==0){p=cte(c);return;}
    if(val[p]==c){cnt[p]++;update(p);return;}
    if(c<val[p]){insert(l[p],c);if(dat[p]<dat[l[p]])zig(p);}
    else {insert(r[p],c);if(dat[p]<dat[r[p]])zag(p);}
    update(p);
}
void remove(int &p,int c)
{
    if(p==0)return;
    if(val[p]==c){
    if(cnt[p]>1){cnt[p]--;update(p);return;}
    if(l[p]||r[p])
    {if(r[p]==0||dat[r[p]]<dat[l[p]])zig(p),remove(r[p],c);
    else zag(p),remove(l[p],c);
    update(p);}
    else p=0;
    return;}
    c<val[p]?remove(l[p],c):remove(r[p],c);
    update(p);
}
int grbv(int p,int c)
{
    if(p==0)return 0;
    if(c==val[p])return size[l[p]]+1;
    if(c<val[p])return grbv(l[p],c);
    return grbv(r[p],c)+cnt[p]+size[l[p]];
}
int gvbr(int p,int rk){
    if(p==0)return inf;
    if(size[l[p]]>=rk)return gvbr(l[p],rk);
    if(size[l[p]]+cnt[p]>=rk)return val[p];
    return gvbr(r[p],rk-cnt[p]-size[l[p]]);
}
int getpre(int c){
    int ans=1,p=root;
    while(p){
        if(c==val[p]){if(l[p]>0){p=l[p];while(r[p]>0)p=r[p];ans=p;}break;}
        if(val[p]<c&&val[ans]<val[p])ans=p;
        p=c<val[p]?l[p]:r[p];
    }
    return val[ans];
}
int getnxt(int c){
    int ans=2,p=root;
    while(p){
        if(c==val[p]){if(r[p]>0){p=r[p];while(l[p]>0)p=l[p];ans=p;}break;}
        if(val[p]>c&&val[ans]>val[p])ans=p;
        p=c<val[p]?l[p]:r[p];
    }
    return val[ans];
}
int main()
{
    build();
   cin>>t;
   while(t--)
   {
       int opt,c;
       cin>>opt>>c;
       if(opt==1)insert(root,c);
    if(opt==2)remove(root,c);
    if(opt==3)cout<<(grbv(root,c)-1)<<endl;
    if(opt==4)cout<<gvbr(root,c+1)<<endl;
    if(opt==5)cout<<getpre(c)<<endl;
    if(opt==6)cout<<getnxt(c)<<endl;
    }    
}
原文地址:https://www.cnblogs.com/SFWR-YOU/p/11379600.html