样例没过求条,有注释
查看原帖
样例没过求条,有注释
1393199
Folden_xiaoming楼主2025/7/2 12:41

疑似后继和插入出了问题

#include<bits/stdc++.h>
using namespace std;
int n,op,a,lst,root;//lst是最后一个节点的位置
struct node{
	int l,r,sum,val,cnt;//l为左孩子,r为右孩子,sum为子树的节点数量 ,cnt为该节点有几个,val为节点的值 
}bst[110000]; 
void insert(int &pos,int v){//以pos为根插入v 
	if(!pos){//叶子,动态开点 
		lst++;
		pos=lst;
		bst[pos].val=v;
		bst[pos].cnt=1;
		bst[pos].sum=1;
		return;
	}
	if(bst[pos].val==v){//重复 
		bst[pos].cnt++;
		bst[pos].sum++;
		return;
	}
	if(bst[pos].val<v)insert(bst[pos].r,v);//往右 
	else insert(bst[pos].l,v);//往左 
	bst[pos].sum=bst[pos].cnt+bst[bst[pos].l].sum+bst[bst[pos].r].sum;
}
int findth(int pos,int v){//以pos为根v的排名 
	if(!pos)return 1;
	int cc=bst[bst[pos].l].sum;
	if(bst[pos].val==v)return cc+1;
	if(bst[pos].val>v)return findth(bst[pos].l,v); 
	else return findth(bst[pos].r,v)+cc+bst[pos].cnt; 
}
int findkth(int pos,int k){//以pos为根的排名为k的数的编号 
	if(!pos)return 0;
	int cc=bst[bst[pos].l].sum;
	if(cc>=k)return findkth(bst[pos].l,k);
	else if(cc<k&&cc+bst[pos].cnt>=k)return pos;
	else return findkth(bst[pos].r,k-cc-bst[pos].cnt);
}
int pre(int pos,int v,int ans){//以pos为根的v的前驱,ans为暂时答案 
	if(!pos)return ans;
	if(bst[pos].val>=v)return pre(bst[pos].l,v,ans);
	else  return pre(bst[pos].r,v,max(ans,bst[pos].val));
} 
int nxt(int pos,int v,int ans){//以pos为根的v的后继,ans为暂时答案 
	if(!pos)return ans;
	if(bst[pos].val<=v)return pre(bst[pos].r,v,ans);
	else return nxt(bst[pos].l,v,min(ans,bst[pos].val));
} 
int main(){
	cin>>n;
    insert(root,INT_MIN);
	insert(root,INT_MAX);
	while(n--){
		cin>>op>>a;
		if(op==1) cout<<findth(root,a)-1<<endl;
		else if(op==2) cout<<bst[findkth(root,a+1)].val<<endl;
		else if(op==3) cout<<pre(root,a,INT_MIN)<<endl;
		else if(op==4) cout<<nxt(root,a,INT_MAX)<<endl;
		else insert(root,a);
	}
	return 0;
}
2025/7/2 12:41
加载中...