社区讨论

大佬们帮我看看哪里出问题了P3369 【模板】普通平衡树

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

讨论操作

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

当前回复
3 条
当前快照
1 份
快照标识符
@lo2w2yli
此快照首次捕获于
2023/10/23 20:44
2 年前
此快照最后确认于
2023/10/23 20:44
2 年前
查看原帖
CPP
#include<bits/stdc++.h>
using namespace std;
const int INF=0x7fffffff;
int ans;
struct node{
	int size;
	int rank;
	int key;
	int num;
	node *son[2];
	int cmp(int x)const{
		if(x==key)return -1;
		return x<key?0:1;
	}
	void update(){
		size=num;
		if(son[0]!=NULL)size=size+son[0]->size;
		if(son[1]!=NULL)size=size+son[1]->size;
	}
};
void rotate(node *&o,int d){
	node *k=o->son[d^1];
	o->son[d^1]=k->son[d];
	k->son[d]=o;
	o->update();
	k->update();
	o=k;
}
void insert(node* &o,int x){
	if(o==NULL){
		o=new node();
		o->son[0]=NULL;
		o->son[1]=NULL;
		o->rank=rand();
		o->key=x;
		o->num=1;
		o->size=1;
	}
	else{
		if(o->key==x){
		o->num+=1;
		o->update();
		return;
		}
		int d=o->cmp(x);
		insert(o->son[d],x);
		o->update();
		if((o->rank)<(o->son[d]->rank)){
			rotate(o,d^1);
		}
	}
}
int kth(node *o,int k){
	if(o==NULL||k<=0||k>o->size)return -1;
	int s=o->son[0]==NULL?0:o->son[0]->size;
	if(k==s+1)return o->key;
	else if(k<=s)return kth(o->son[0],k);
	else return kth(o->son[1],k-s-1); 
}
int found(node *o,int k){
	if(o==NULL){
		return -1;
	}
	int d=o->cmp(k);
	if(d==-1)return o->son[0]==NULL?1:o->son[0]->size+1;
	else if(d==0) return found(o->son[d],k);
	else{
		int tmp=found(o->son[d],k);
		if(tmp==-1){
			return -1;
		}
		else{
			return o->son[0]==NULL?tmp+1:tmp+1+o->son[0]->size;
		}
	}
}
void rmove(node* &o,int k)
{
    if (o==NULL) return;
    int d=o->cmp(k);
    if (d<0)
     {
        if (o->num>1) {o->num--; o->size--; return;}
         else if (o->son[0]==NULL) o=o->son[1];
          else if (o->son[1]==NULL) o=o->son[0];
           else if (o->son[0]->rank<o->son[1]->rank) {rotate(o,0); rmove(o,k);} else {rotate(o,1); rmove(o,k);}
     }
     else rmove(o->son[d],k);
     if(o!=NULL){
     	o->update();
	 }
}
int get_pre(node *o, int k) { 
    if (o == NULL) return -INF;
    if (o->key >= k) return get_pre(o->son[0], k);
    return max(o->key, get_pre(o->son[1], k));
}
int get_next(node *o, int k) {
    if (o == NULL) return INF;
    if (o->key <= k) return get_next(o->son[1], k);
    return min(o->key, get_next(o->son[0], k));
}
int main(){
	int n,k,g;
	srand(time(NULL));
	node *root;
	root=new node();
	root=NULL;
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		scanf("%d%d",&g,&k);
		if(g==1)insert(root,k);
		if(g==2)rmove(root,k);
		if(g==3)printf("%d\n",found(root,k));
		if(g==4){
			printf("%d\n",kth(root,k));
		}
		if(g==5){
			printf("%d\n",get_pre(root,k));
		}
		if(g==6){
			printf("%d\n",get_next(root,k));
		}
	}
	return 0; 
}

回复

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

正在加载回复...