社区讨论

萌新刚学Treap求助

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

讨论操作

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

当前回复
5 条
当前快照
1 份
快照标识符
@mi86jjd5
此快照首次捕获于
2025/11/21 09:26
4 个月前
此快照最后确认于
2025/11/21 09:26
4 个月前
查看原帖
QNDMX就别说了吧QAQ
表示按照某本垃圾教材的代码写的,然后就挂了qaq
52分
CPP
# include <bits/stdc++.h>
# define rr register
# define lc(x) tree[x].lc
# define rc(x) tree[x].rc
# define cnt(x) tree[x].cnt
# define pro(x) tree[x].pro
# define size(x) tree[x].size
# define val(x) tree[x].val
const int N=100010,INF=1e9;
struct node{
    int lc,rc,cnt,pro,size,val;
}tree[N];
int root,t;
int n;
inline int read(void);//快读 
inline void Update(int &);
inline void Right(int &);//右旋 
inline void Left(int &);//左旋 
void Insert(int &,int);
void Delete(int &,int);
inline int FindPre(int);
inline int FindNext(int);
inline int kth(int);
inline int Rank(int);
int main(void){
    srand(time(0));
    n=read();
    int opt,x;
    while(n--){
        opt=read(),x=read();
        switch(opt){
            case 1:Insert(root,x);break;
            case 2:Delete(root,x);break;
            case 3:printf("%d\n",Rank(x));break;
            case 4:printf("%d\n",kth(x));break;
            case 5:printf("%d\n",FindPre(x));break;
            case 6:printf("%d\n",FindNext(x));break;
            default:break;
        }
    } 
    return 0;
}
inline int read(void){
    int res,f=1;
    char c;
    while((c=getchar())<'0'||c>'9')
        if(c=='-')f=-1;
    res=c-48;
    while((c=getchar())>='0'&&c<='9')
        res=res*10+c-48;
    return res*f;		
}
inline void Update(int &x){
    size(x)=size(lc(x))+size(rc(x))+cnt(x);
    return;
}
inline void Right(int &x){
    int y=lc(x);
    lc(x)=rc(y);
    rc(y)=x;
    size(y)=size(x);
    Update(x);
    x=y;
    return;
}
inline void Left(int &x){
    int y=rc(x);
    rc(x)=lc(y);
    lc(y)=x;
    size(y)=size(x);
    Update(x);
    x=y;
    return;
}
void Insert(int &x,int val){
    if(!x){
        x=++t;
        size(x)=cnt(x)=1;
        val(x)=val;
        pro(x)=rand();
        return;
    }
    ++size(x);
    if(val==val(x)){
        ++cnt(x);
        return;
    }
    if(val<val(x)){
        Insert(lc(x),val);
        if(pro(lc(x))<pro(x))
            Right(x);
        return;	
    }
    Insert(rc(x),val);
    if(pro(rc(x))<pro(x))
        Left(x);
    return;	
}
void Delete(int &x,int val){
    if(val==val(x)){
        if(cnt(x)>1){
            --cnt(x),--size(x);
            return;
        }
        if(!lc(x)||!rc(x)){
            x=lc(x)+rc(x);
            return;		
        }
        if(pro(lc(x))<pro(rc(x))){
            Right(x);
            Delete(x,val);
        }
        else{
            Left(x);
            Delete(x,val);
        }
        return;
    }
    --size(x);
    if(val<val(x))
        Delete(lc(x),val);
    else
        Delete(rc(x),val);
    return;
}
inline int FindPre(int val){
    int x=root,res=-INF;
    while(x){
        if(val(x)<=val)
            res=val(x),x=rc(x);
        else
            x=lc(x);
    }
    return res;
}
inline int FindNext(int val){
    int x=root,res=INF;
    while(x){
        if(val(x)>=val)
            res=val(x),x=lc(x);
        else
            x=rc(x);
    }
    return res;
}
inline int kth(int rk){
    int x=root;
    while(x){
        if(size(lc(x))<rk&&size(lc(x))+cnt(x)>=rk)
            return val(x);
        if(size(lc(x))>=rk)
            x=lc(x);
        else
            rk-=(size(lc(x))+cnt(x)),x=rc(x);	
    }
    return -1;
}
inline int Rank(int val){
    int x=root,res=0;
    while(x){
        if(val==val(x))
            return res+size(lc(x))+1;
        if(val<val(x))
            x=lc(x);
        else
            res+=size(lc(x))+cnt(x),x=rc(x);
    }
    return res;
}

回复

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

正在加载回复...