FHQ,21pts求调
查看原帖
FHQ,21pts求调
1085667
KohaD_SEGA楼主2023/11/1 23:52
#include <bits/stdc++.h>
#define N 100007
#define TreeL(x) tree[tree[(x)].left]
#define TreeR(x) tree[tree[(x)].right]
using namespace std;
stack<int> numset;
int root;
inline int Rdom(void)
{
	return (rand()%172281+2)^(rand()%9982443+1)+rand()>>13;
}
struct Btree
{
	int num;
	int val;
	int left;
	int right;
	int size;
};
Btree tree[N];
inline int mkpt(int x)
{
	int tot=numset.top();
	tree[tot].num=x;
	tree[tot].val=Rdom();
	tree[tot].size=1;
	numset.pop();
	return tot;
}
inline void push_up(int p)
{
	tree[p].size=1+TreeL(p).size+TreeR(p).size;
	return;
}
void split(int p,int num,int &lef,int &rig)
{
	if(p==0)
	{
		lef=rig=0;
		return;
	}
	if(tree[p].num<=num)
	{
		lef=p;
		split(tree[p].right,num,tree[p].right,rig);
	}
	else
	{
		rig=p;
		split(tree[p].left,num,lef,tree[p].left);
	}
}
int merge(int lef,int rig)
{
	if(lef==0 || rig==0)	return lef+rig;
	if(tree[lef].val>tree[rig].val)
	{
		tree[lef].right=merge(tree[lef].right,rig);
		push_up(lef);
		return lef;
	}
	else
	{
		tree[rig].left=merge(lef,tree[rig].left);
		push_up(rig);
		return rig;
	}
}
inline void addin(int num)
{
	int tot=mkpt(num);
	int l,r;
	split(root,num-1,l,r);
	root=merge(merge(l,tot),r);
}
inline void delet(int num)
{
	int l,r,pos;
	split(root,num,l,r);
	split(l,num-1,l,pos);
	numset.push(pos);
	if(pos)	pos=merge(tree[pos].left,tree[pos].right);
	root=merge(merge(l,pos),r);
}
inline int rks(int num)
{
	int l,r;
	split(root,num-1,l,r);
	return tree[l].size+1;
}
inline int getrks(int rk)
{
	int ans=root;
	while(ans)
	{
		if(rk==TreeL(ans).size+1)	break;
		else if (rk<=TreeL(ans).size) ans=tree[ans].left;
		else	rk-=TreeL(ans).size+1,ans=tree[ans].right;
	}
	return ans==0?INT_MAX:tree[ans].num;
}
inline int getpre(int num)
{
	int l,r,ans;
	split(root,num-1,l,r);
	ans=l;
	while(tree[ans].right) ans=tree[ans].right;
	return tree[ans].num;
}
inline int getnex(int num)
{
	int l,r,ans;
	split(root,num,l,r);
	ans=r;
	while(tree[ans].left)	ans=tree[ans].left;
	return tree[ans].num;
}
int main()
{
	srand((unsigned)time(NULL));
	int n;
	scanf("%d",&n);
	for(int i=n+1;i>=1;i--)	numset.push(i);
	int opt,num;
	while(n--)
	{
		scanf("%d%d",&opt,&num);
		switch(opt)
		{
			case 1:addin(num);break;
			case 2:delet(num);break;
			case 3:printf("%d\n",rks(num));break;
			case 4:printf("%d\n",getrks(num));break;
			case 5:printf("%d\n",getpre(num));break;
			case 6:printf("%d\n",getnex(num));break;
		}
	}
	return 0;
}
2023/11/1 23:52
加载中...