社区讨论

本人萌新,初学OI,替罪羊数写炸了QAQ

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

讨论操作

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

当前回复
16 条
当前快照
1 份
快照标识符
@mi6xurxa
此快照首次捕获于
2025/11/20 12:35
4 个月前
此快照最后确认于
2025/11/20 15:23
4 个月前
查看原帖
CPP
#include<bits/stdc++.h>
const int MAXN=100010;
const int INF=0x7f7f7f7f;
const double alpha=0.75;
typedef double D;
using namespace std;
int n,m,i,j,k,opt,x;
struct sgt{
    int lson,rson,size,val,tot,exist=1;
};
sgt tree[MAXN];
int g[MAXN],temp[MAXN],g_t,root,t_t;
struct io{
    int read(){
        int x=0;char c;
        for(c=getchar();!isdigit(c);c=getchar()) ;
        for(;isdigit(c);c=getchar()) x=x*10+c-48;
        return x;
    }
    void write(int x){
        if(x/10>0) write(x/10);
        putchar(x%10+48);
        return;
    }
}Fio;
#define read Fio.read
#define write Fio.write
namespace SGT{
    bool bad(int x){
        if((D)(max(tree[tree[x].lson].size,tree[tree[x].rson].size))>=tree[x].size*alpha) return 1;
        else return 0;		
    }
    void dfs(int x){
        if(x==0) return;
        dfs(tree[x].lson);
        if(tree[x].exist==1) temp[++t_t]=x;
        else g[++g_t]=x;
        dfs(tree[x].rson);	
    }
    void bulid(int l,int r,int&now){
        int mid=(l+r)/2;
        now=temp[mid]; 
        if(l==r){
            tree[now].lson=0;tree[now].rson;
            tree[now].size=1;tree[now].tot=1;tree[now].exist=1;
            return;
        }
        if(l<mid) bulid(l,mid-1,tree[now].lson);
        else tree[now].lson=0;  
        bulid(mid+1,r,tree[now].rson);
        tree[now].size=tree[tree[now].lson].size+tree[tree[now].rson].size+1;
        tree[now].tot=tree[tree[now].lson].tot+tree[tree[now].rson].tot+1;
        return;
    }  
    void rebuild(int&now){
        t_t=0;
        dfs(now);
        if(t_t==0) bulid(1,t_t,now);
        else now=0;
    } 
    void insert(int &now,int val){
        if(now==0){
            now=g[g_t--];
            tree[now].val=val;
            tree[now].lson=0;tree[now].rson=0;
            tree[now].size=1;tree[now].exist=1;tree[now].tot=1;
            return;
        }
        tree[now].size++;tree[now].tot++;
        if(tree[now].val>=val) insert(tree[now].lson,val);
        else insert(tree[now].rson,val);
        if(bad(now)==1) rebuild(now);
    }
    int Qrank(int k){
        int now=root;
        int ans=1;
        while(now>0){
            if(tree[now].val>=k) now=tree[now].lson;
            else{
                ans+=tree[tree[now].lson].size+tree[tree[now].rson].exist;   
                now=tree[now].rson;
            }
        }
        return ans;
    }
    int Frank(int k){
        int now=root;
        while(now>0){
            if(tree[now].exist==1&&tree[tree[now].lson].size+1==k) return tree[now].val;
            else if(tree[tree[now].lson].size+1>k) now=tree[now].lson;
            else{
                k-=(tree[tree[now].lson].size+tree[now].exist);
                now=tree[now].rson;		
            }
        }  
        return INF; 
    }
    void delRank(int &now,int k){
        if(tree[now].exist==1&&tree[tree[now].lson].size+1==k){
            tree[now].exist=0;tree[now].size--;
            return;			
        }
        tree[now].size--;
        if(tree[tree[now].lson].size+1>=k){
            now=tree[now].lson;
            delRank(now,k);
        }
        else{
            now=tree[now].rson;
            k-=(tree[tree[now].lson].size+tree[now].exist);
            delRank(now,k);
        }
        return; 
    }
    void delNode(int k){
        delRank(root,Frank(k));
        if(tree[root].tot*alpha>=tree[root].size) rebuild(root);
    }
}
int main(){    
    n=read();
    for(int _i=MAXN-1;_i>=1;_i--) g[++g_t]=_i;   
    for(int _i=1;_i<=n;_i++){
        scanf("%d %d",&opt,&x);
        if(opt==1) SGT::insert(root,x);
        else if(opt==2) SGT::delNode(x);
        else if(opt==3) printf("%d\n",SGT::Qrank(x));
        else if(opt==4) printf("%d\n",SGT::Frank(x));  
        else if(opt==5) printf("%d\n",SGT::Frank(SGT::Qrank(x)-1));
        else printf("%d\n",SGT::Frank(SGT::Qrank(x+1)));
    } 
}

回复

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

正在加载回复...