20分求助,萌新刚学fhqtreap
查看原帖
20分求助,萌新刚学fhqtreap
486187
vvautedSN第一魔怔人楼主2021/7/22 23:16
#include <stdio.h>
#define Maxn 100005
int L[Maxn],R[Maxn],ans;
int val[Maxn],rand[Maxn],siz[Maxn];
int tot,root,x,y,z;
void push_up(int p){siz[p]=siz[L[p]]+siz[R[p]]+1;}
void split(int p,int k,int &x,int &y)
{
	if(!p) {x=y=0;return;}
	if(val[p]<=k) x=p,split(R[p],k,R[p],y);
	else y=p,split(L[p],k,x,L[p]);
	push_up(p);
}
int merge(int u,int v)
{
	if(!u||!v) return v+u;
	if(rand[u]<rand[v]) {R[u]=merge(R[u],v);push_up(u);return u;}
	else {L[v]=merge(u,L[v]);push_up(v);return v;}
}
int rnd=111132484;
int get_rand()
{
	return rnd=(rnd*1433223%1000000000);
}
int new_node(int x)
{
	val[++tot]=x,siz[tot]=1,rand[tot]=get_rand();
	return tot;
}
void insert(int a)
{
	split(root,a,x,y);
	root=merge(merge(x,new_node(a)),y);
}
void del(int a)
{
	split(root,a,x,y),split(x,a-1,x,y),root=merge(merge(x,merge(L[y],R[y])),z);//df
}
int findkth(int p,int k)
{
	if(siz[L[p]]+1==k) return p;
	if(siz[L[p]]>=k) return findkth(L[p],k);
	return findkth(R[p],k-siz[L[p]]-1);
}
int findrank(int a)
{
	split(root,a-1,x,y),ans=siz[x]+1,root=merge(x,y);
	return ans;
}
int front(int a)
{
	split(root,a-1,x,y),ans=findkth(x,siz[x]),root=merge(x,y);
	return ans;
}
int back(int a)
{
	split(root,a,x,y),ans=findkth(y,1),root=merge(x,y);
	return ans;	
}
int main()
{
	int n,opt,a;
	scanf("%d",&n);
	while(n--)
	{
		scanf("%d%d",&opt,&a);
		if(opt==1) insert(a);
		if(opt==2) del(a);
		if(opt==3) printf("%d\n",val[findrank(a)]);
		if(opt==4) printf("%d\n",val[findkth(root,a)]);
		if(opt==5) printf("%d\n",val[front(a)]);
		if(opt==6) printf("%d\n",val[back(a)]);
		//printf("%d\n",siz[1]);
	}
}
2021/7/22 23:16
加载中...