社区讨论

有一个有点唐氏的问题

P3369【模板】普通平衡树参与者 3已保存回复 2

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
2 条
当前快照
1 份
快照标识符
@mhjhmqns
此快照首次捕获于
2025/11/04 02:43
4 个月前
此快照最后确认于
2025/11/04 02:43
4 个月前
查看原帖
CPP
#include <bits/stdc++.h>
using namespace std;

int rd[300005],son[300005][2],size[300005],num[300005],v[300005];
int R=0;
void pushup(int w){
    size[w]=size[son[w][0]]+size[son[w][1]]+num[w];
}
void rotate(int &w,int d){
    int k=son[w][d^1];
    son[w][d^1]=son[k][d];
    son[k][d]=w;
    pushup(w);
    pushup(k);
    w=k;
}
int cnt;
void insert(int &w,int x){
    if (!w){
        w=++cnt;
        size[w]=num[w]=1;
        v[w]=x;
        rd[w]=rand();
        return;
    }
    if (v[w]==x){
        num[w]++;size[w]++;
        return;
    }
    int d=(x>v[w]);
    insert(son[w][d],x);
    if (rd[w]<rd[son[w][d]]) rotate(w,d^1);
    pushup(w);
}
void del(int &w,int x){
    if(w==0) return;
    if (x<v[w]) del(son[w][0],x);
    else if (x>v[w]) del(son[w][1],x);
    else{
        if (son[w][0]==0&&son[w][1]==0){
            num[w]--;size[w]--;
            if (num[w]==0) w=0;
        }
        else if (son[w][0]==1&&son[w][1]==0){
            rotate(w,1);
            del(son[w][0],x);
        }
        else if (son[w][1]==1&&son[w][0]==0){
            rotate(w,0);
            del(son[w][1],x);
        }
        else{
            int d=rd[son[w][0]]>rd[son[w][1]];
            rotate(w,d);
            del(son[w][d],x);
        }
    }
    pushup(w);
}
int rk(int p,int x){
    if (p==0) return 1;
    if (v[p]==x) return size[son[p][0]]+1;
    if (v[p]<x) return size[son[p][0]]+num[p]+rk(son[p][1],x);
    return rk(son[p][0],x);
}
int find(int p,int x){
    if (!p) return 0;
    if (size[son[p][0]]>=x) return find(son[p][0],x);
    if (size[son[p][0]]+num[p]>=x) return v[p];
    return find(son[p][1],x-size[son[p][0]]-num[p]);
}
int pre(int p,int x){
    if (p==0) return -2147483647;
    if (v[p]>=x) return pre(son[p][0],x);
    else return max(v[p],pre(son[p][1],x));
}
int suc(int p,int x){
    if (p==0) return 2147483647;
    if (v[p]<=x) return suc(son[p][1],x);
    return min(v[p],suc(son[p][0],x));
}
int main(){
//   srand(time(NULL));
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    int n;
    cin>>n;
    for(int i=1;i<=n;i++){
        int op,x;
        cin>>op>>x;
        if (op==1) insert(R,x);
        if (op==2) del(R,x);
        if (op==3) cout<<rk(R,x)<<endl;
        if (op==4) cout<<find(R,x)<<endl;
        if (op==5) cout<<pre(R,x)<<endl;
        if (op==6) cout<<suc(R,x)<<endl;
    }
    return 0;
}
如果不注释rand就过不了,注释了就过了,求问。

回复

2 条回复,欢迎继续交流。

正在加载回复...