平衡树求调
查看原帖
平衡树求调
199459
Masna_Kimoyo楼主2021/11/19 01:14

24pts,真的不知道哪错了qwq,调了几个小时了

treap写的,下载了数据点,目测是在Delete函数上出了问题,但看了很久却又感觉没错

求神仙救救我/dk/dk/dk

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+5,INF=2147483647;
int n;
namespace Treap{
	int root,tot=0;
	struct node{
		int val,rand,size,cnt;
		int son[2];	
	}tree[N];
	#define push_up(x) tree[x].size=tree[tree[x].son[0]].size+tree[tree[x].son[1]].size+tree[x].cnt
	inline int New_node(int x){
		tree[++tot]=(node){x,rand(),1,1};
		return tot;
	}
    inline void Rotate(int &x,bool v){
        int s=tree[x].son[v];
        tree[x].son[v]=tree[s].son[!v];
        tree[s].son[!v]=x;
        x=s;push_up(tree[x].son[!v]),push_up(x);
    }
    inline void Insert(int &x,int v){
        if(!x){
            x=New_node(v);
            return ;
        }
        if(v==tree[x].val)  ++tree[x].cnt;    
        else{
            int d=v>=tree[x].val;
            Insert(tree[x].son[d],v);
            if(tree[x].rand<tree[tree[x].son[d]].rand)  Rotate(x,d);
        }
        push_up(x);	
    }
    inline void Delete(int &x,int v){
        if(!x)  return ;
        if(v==tree[x].val){
            if(tree[x].cnt>1){
                --tree[x].cnt;
                push_up(x);
                return ;
            }
            if(tree[x].son[0] || tree[x].son[1]){
                bool d=(!tree[x].son[1] || tree[tree[x].son[0]].rand>tree[tree[x].son[1]].rand);
                Rotate(x,d),Delete(tree[x].son[d],v);
                push_up(x);
            }
            else x=0;
            return ;
        }
        if(v<tree[x].val)   Delete(tree[x].son[0],v);
        else    Delete(tree[x].son[1],v);
        push_up(x);
    }
    inline int get_rnk(int x,int v){
        if(!x)  return 0;
        if(v==tree[x].val)  return tree[tree[x].son[0]].size+1;
        else    if(v<tree[x].val)   return get_rnk(tree[x].son[0],v);
        else    return tree[tree[x].son[0]].size+tree[x].cnt+get_rnk(tree[x].son[1],v);
    }
    inline int get_val(int x,int rk){
        if(!x)  return INF;
        if(rk<=tree[tree[x].son[0]].size)   return get_val(tree[x].son[0],rk);
        else    if(rk<=tree[tree[x].son[0]].size+tree[x].cnt)   return tree[x].val;
        else    return get_val(tree[x].son[1],rk-tree[tree[x].son[0]].size-tree[x].cnt);
    }
    inline int get_pre(int v){
        int x=root,pre=0;
        while(x){
        	if(tree[x].val<v)	pre=tree[x].val,x=tree[x].son[1];
        	else	x=tree[x].son[0];
		}
		return pre;
    }
    inline int get_nxt(int v){
    	int x=root,nxt=0;
    	while(x){
    		if(tree[x].val>v)	nxt=tree[x].val,x=tree[x].son[0];
    		else	x=tree[x].son[1];
		}
		return nxt;
	}
}
using namespace Treap;
inline int read(){
    int x=0;
    bool w=0;
    char c=getchar();
    while(!isdigit(c))  w|=c=='-',c=getchar();
    while(isdigit(c))   x=(x<<1)+(x<<3)+(c^48),c=getchar();
    return w?-x:x;
}
inline void print(int x){
    if(x<0) x=-x,putchar('-');
    if(x>9) print(x/10);
    putchar('0'+x%10);
}
inline void printlf(int x){
    print(x),putchar('\n');
}
inline void printsp(int x){
    print(x),putchar(' ');
}
signed main(){
    n=read();
    while(n--){
    	int op=read(),x=read();
    	if(op==1)	Insert(root,x);
    	if(op==2)	Delete(root,x);
    	if(op==3)	printlf(get_rnk(root,x));
    	if(op==4)	printlf(get_val(root,x));
    	if(op==5)	printlf(get_pre(x));
    	if(op==6)	printlf(get_nxt(x));
	}
    return 0;
}
2021/11/19 01:14
加载中...