100pts hack点求调
查看原帖
100pts hack点求调
964148
cqbzrjx楼主2024/7/9 09:17
/*
LuoGu P5076【深基16.例7】普通二叉树(简化版) 
*/
#include <bits/stdc++.h>
using namespace std;
const int maxn = 100005;
int n,root,cnt,opt,x;
struct node
{
	int left,right,size,value,num;
	node(int l,int r,int s,int v) : left(l),right(r),size(s),value(v),num(1){}
	node(){}
}tree[maxn];
inline void update(int root)
{
	tree[root].size = tree[tree[root].left].size + tree[tree[root].right].size + tree[root].num;
}//更新结点信息 
inline int rk(int x,int root)//查询排名
{
	if(root)
	{
		if(x < tree[root].value) return rk(x,tree[root].left);
		if(x > tree[root].value) return rk(x,tree[root].right) + tree[tree[root].left].size + tree[root].num;
		//左子树所有数都比x要小,故进入右子树并且加上左子树size
		return tree[tree[root].left].size + tree[root].num; 
	}
	return 1;
}
inline int kth(int x,int root)//查询排名为x的数
{
	if(x <= tree[tree[root].left].size) return kth(x,tree[root].left);
	if(x <= tree[tree[root].left].size + tree[root].num) return tree[root].value;
	return kth(x - tree[tree[root].left].size - tree[root].num,tree[root].right);
}
inline void insert(int x,int &root)//插入值为x的数 
{
	if(x < tree[root].value)//插入左子树 
	{
		if(!tree[root].left) tree[tree[root].left = ++cnt] = node(0,0,1,x);
		else insert(x,tree[root].left);
	}
	else if(x > tree[root].value)//插入右子树
	{
		if(!tree[root].right) tree[tree[root].right = ++cnt] = node(0,0,1,x);
		else insert(x,tree[root].right);
	}
	else tree[root].num++;//x结点已经存在,结点大小+1 
	update(root);
}
signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
	cin>>n;
	int num = 0;
	tree[root = ++ cnt] = node(0,0,1,2147483647);
	while(n--)
	{
		cin>>opt>>x;
		num++;
		if(opt == 1)
		{
			cout<<rk(x,root)<<endl; 
		}
		else if(opt == 2)
		{
			cout<<kth(x,root)<<endl;
		}
		else if(opt == 3)
		{
			cout<<kth(rk(x,root) - 1,root)<<endl;
		}
		else if(opt == 4)
		{
			cout<<kth(rk(x + 1,root),root)<<endl;
		}
		else
		{
			num--;
			insert(x,root);
		}
	}
	return 0;
}
2024/7/9 09:17
加载中...