FHQ求调玄关
查看原帖
FHQ求调玄关
600441
ZhongYuLin楼主2023/9/25 11:34
#include<cstdio>
#include<cmath>
using namespace std;
const int maxn=5e6+10;
struct pair{
    int a,b;//左右子树的根
    pair(int _a,int _b){a=_a;b=_b;}
    pair(){a=b=0;}
};
int ch[maxn][2],size[maxn],cnt[maxn],key[maxn],val[maxn];
int tot,root,n,op,x;
void push_up(int cur){
    size[cur]=size[ch[cur][0]]+size[ch[cur][1]]+cnt[cur];
}
void add(int k){
    val[++tot]=k;
    key[tot]=rand();
    cnt[tot]=1;//该val的个数
    size[tot]=1;
}
pair split(int cur,int k){
    if(!cur)return pair();
    if(val[cur]<=k){
        pair t=split(ch[cur][1],k);
        ch[cur][1]=t.a;
        push_up(cur);
        return pair(cur,t.b);
    }else{
        pair t=split(ch[cur][0],k);
        ch[cur][0]=t.b;
        push_up(cur);
        return pair(t.a,cur);
    }
}
int merge(int u,int v){
    if(!u||!v)return u+v;
    if(key[u]<key[v]){
        ch[u][1]=merge(ch[u][1],v);
        push_up(u);
        return u;
    }else{
        ch[v][0]=merge(u,ch[v][0]);
        push_up(v);
        return v;
    }
}
void insert(int k){
    pair t=split(root,k);
    int x=t.a;
    while(x){
        if(val[x]==k){
            cnt[x]++;
            root=merge(t.a,t.b);
            return;
        }
        x=ch[x][1];
    }
    add(k);
    root=merge(merge(t.a,tot),t.b);
}
void dlt(int k){
    pair t1=split(root,k);
    pair t2=split(t1.a,k-1);
    if(--cnt[t2.b])t1.a=merge(t2.a,t2.b);
    else t1.a=t2.a;
    root=merge(t1.a,t1.b);
}
int get_rank(int k){
    pair t=split(root,k);
    int x=t.a,ans;
    while(x){
        if(val[x]==k){
            ans=size[t.a]-cnt[x]+1;
            merge(t.a,t.b);
            return ans;
        }
        x=ch[x][1];
    }
    ans=size[t.a]+1;
    root=merge(t.a,t.b);
    return ans;
}
int get_val(int rk){
    int x=root;
    while(rk){
        if(size[ch[x][0]]<rk&&rk<=size[ch[x][0]]+cnt[x])return val[x];
        else if(rk<=size[ch[x][0]])x=ch[x][0];
        else rk-=size[ch[x][0]]+cnt[x],x=ch[x][1];
    }
    return val[x];
}
int get_pre(int x){
    return get_val(get_rank(x)-1);
}
int get_next(int x){
    return get_val(get_rank(x+1));
}
int main(){
    //freopen("P6131.in","r",stdin);
    //freopen("P6131.out","w",stdout);
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d%d",&op,&x);
        if(op==1)insert(x);
        else if(op==2)dlt(x);
        else if(op==3)printf("%d\n",get_rank(x));
        else if(op==4)printf("%d\n",get_val(x));
        else if(op==5)printf("%d\n",get_pre(x));
        else printf("%d\n",get_next(x));
    }
    return 0;   
}
2023/9/25 11:34
加载中...