社区讨论
有一个有点唐氏的问题
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 条回复,欢迎继续交流。
正在加载回复...