社区讨论
关于Treap随机数的疑问
P3369【模板】普通平衡树参与者 4已保存回复 5
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 5 条
- 当前快照
- 1 份
- 快照标识符
- @m4y9r3un
- 此快照首次捕获于
- 2024/12/21 22:22 去年
- 此快照最后确认于
- 2025/11/04 12:30 4 个月前
为什么一下代码在
CPPmt19937生成的随机数下只能通过部分测试点(每次数量有不同),但用rand()却能通过此题?#include<bits/stdc++.h>
#define lson a[p].l
#define rson a[p].r
#define inf 0x7fffffff
const int N=1e5+10;
struct Treap{
int l,r;
int dat,val;
int cnt,siz;
}a[N];
int tot,root;
//std::mt19937 rd(std::time(nullptr));
int New(int val){
a[++tot].val=val;
a[tot].cnt=a[tot].siz=1;
a[tot].dat=std::rand();
return tot;
}
void update(int p){
a[p].siz=a[p].cnt+a[a[p].l].siz+a[a[p].r].siz;
}
void build(){
New(-inf),New(inf);
root=1;a[1].r=2;
update(root);
}
int rank_by_val(int p,int val){
if(p==0)return 1;
if(a[p].val==val)return a[a[p].l].siz+1;
if(val<a[p].val)return rank_by_val(a[p].l,val);
else return rank_by_val(a[p].r,val)+a[a[p].l].siz+a[p].cnt;
}
int val_by_rank(int p,int rk){
if(p==0)return inf;
if(a[a[p].l].siz>=rk)return val_by_rank(a[p].l,rk);
if(a[a[p].l].siz+a[p].cnt>=rk)return a[p].val;//
else return val_by_rank(a[p].r,rk-a[a[p].l].siz-a[p].cnt);
}
void zig(int &p){//右旋,p为变成右子节点的父节点
int q=a[p].l;
a[p].l=a[q].r,a[q].r=p,p=q;
update(a[p].r);update(p);
}
void zag(int &p){//左旋,p为变成左子节点的父节点
int q=a[p].r;
a[p].r=a[q].l,a[q].l=p,p=q;
update(a[p].l);update(p);
}
void Insert(int &p,int val){
if(p==0){
p=New(val);
return ;
}
if(val==a[p].val){
a[p].cnt++;update(p);
return ;
}
if(val<a[p].val){
Insert(a[p].l,val);
if(a[p].dat<a[lson].dat)zig(p);
}else{
Insert(a[p].r,val);
if(a[p].dat<a[rson].dat)zag(p);
}
update(p);
}
void Remove(int &p,int val){
if(p==0)return ;
if(val==a[p].val){
if(a[p].cnt>1){
a[p].cnt--;update(p);
return ;
}
if(a[p].l || a[p].r){
if(a[p].r==0 || a[lson].dat>a[rson].dat){
zig(p);Remove(a[p].r,val);
}else{
zag(p);Remove(a[p].l,val);
}
update(p);
}else p=0;
return ;
}
(val<a[p].val?Remove(a[p].l,val):Remove(a[p].r,val));
update(p);
}
int getpre(int val){
int p=root,ans=1;
while(p){
if(a[p].val<val)ans=p,p=a[p].r;
else p=a[p].l;
}
return a[ans].val;
}
int getnext(int val){
int p=root,ans=2;
while(p){
if(a[p].val>val)ans=p,p=a[p].l;
else p=a[p].r;
}
return a[ans].val;
}
/*
int getpre(int val){
int ans=1;
int p=root;
while(p){
if(val==a[p].val){
if(a[p].l>0){
p=a[p].l;
while(a[p].r>0)p=a[p].r;
ans=p;
}
break;
}
if(a[p].val<val && a[p].val>a[ans].val)ans=p;
p=(val<a[p].val?lson:rson);
}
return a[ans].val;
}
int getnext(int val){
int ans=2;
int p=root;
while(p){
if(val==a[p].val){
if(a[p].r>0){
p=a[p].r;
while(a[p].l>0)p=a[p].l;
ans=p;
}
break;
}
if(a[p].val>val && a[p].val<a[ans].val)ans=p;
p=(val<a[p].val?lson:rson);
}
return a[ans].val;
}
*/
int main(){
//freopen("P3369_1.out","w",stdout);
std::ios::sync_with_stdio(false);
std::cout.tie(nullptr);
std::cin.tie(nullptr);
build();
int q;
std::cin>>q;
while(q--){
int op,x;
std::cin>>op>>x;
if(op==1){
Insert(root,x);
}else if(op==2){
Remove(root,x);
}else if(op==3){
std::cout<<rank_by_val(root,x)-1<<"\n";
}else if(op==4){
std::cout<<val_by_rank(root,x+1)<<"\n";
}else if(op==5){
std::cout<<getpre(x)<<"\n";
}else if(op==6){
std::cout<<getnext(x)<<"\n";
}
//for(int i=1;i<=tot;i++){
// std::cout<<a[i].val<<" "<<a[i].l<<" "<<a[i].r<<" "<<a[i].siz<<" \n";
//}
//std::cout<<"\n";
}
return 0;
}
附上测试结果
回复
共 5 条回复,欢迎继续交流。
正在加载回复...