非旋 Treap 60 pts 求助
查看原帖
非旋 Treap 60 pts 求助
67952
白鲟楼主2021/3/15 17:41

由于其他部分拷的其他平衡树的代码,应该是仅 merge,split,insert,erase 可能出错。

#include<cctype>
#include<cstdio>
#include<cstdlib>
using namespace std;
const int maxn=1e5;
int n,opt,x,root,total,BST[maxn+1],child[maxn+1][2],size[maxn+1],times[maxn+1],priority[maxn+1];
inline void read(int &x)
{
	x=0;
	int signum=1;
	char t=getchar();
	while(!isdigit(t))
	{
		if(t=='-')
			signum=-1;
		t=getchar();
	}
	while(isdigit(t))
	{
		x=x*10+t-'0';
		t=getchar();
	}
	x*=signum;
	return;
}
inline void pushup(int now)
{
	size[now]=size[child[now][0]]+size[child[now][1]]+times[now];
	return;	
}
int merge(int x,int y)
{
	if(!x||!y)
		return x+y;
	int now=0;
	if(priority[x]<priority[y])
		child[now=x][1]=merge(child[x][1],y);
	else child[now=y][0]=merge(x,child[y][0]);
	pushup(now);
	return now;
}
void split(int now,int &x,int &y,int value)
{
	if(!now)
	{
		x=y=0;
		return;
	}
	if(BST[now]<value)
		split(child[x=now][1],child[now][1],y,value);
	else split(child[y=now][0],x,child[now][0],value);
	pushup(now);
	return;
}
void insert(int target)
{
	int x=0,y=0;
	split(root,x,y,target);
	if(BST[y]==target)
	{
		++times[y];
		root=merge(x,y);
	}
	else
	{
		int now=++total;
		times[now]=size[now]=1;
		priority[now]=rand();
		BST[now]=target;
		root=merge(x,merge(now,y));
	}
	return;
}
void erase(int target)
{
	int x=0,y=0,z=0;
	split(root,x,y,target);
	split(y,y,z,target+1);
	if(times[y]>1)
	{
		--times[y];
		root=merge(x,merge(y,z));
	}
	else root=merge(x,z);
	return;
}
int rank_of(int target)
{
    int now=root,res=0;
    while(now)
        if(target==BST[now])
            return res+size[child[now][0]]+1;
        else if(target<BST[now])
            now=child[now][0];
        else
        {
            res+=size[child[now][0]]+times[now];
            now=child[now][1];
        }
    return res+1;
}
int at(int target)
{
    int now=root;
    while(now)
        if(size[child[now][0]]<target&&size[child[now][0]]+times[now]>=target)
            return BST[now];
        else if(size[child[now][0]]>=target)
            now=child[now][0];
        else
        {
            target-=size[child[now][0]]+times[now];
            now=child[now][1];
        }
    return -1;
}
int predecessor(int target)
{
    int res=0;
    for(int i=root;i;i=child[i][target>BST[i]])
        if(target>BST[i])
            res=i;
    return res?BST[res]:-0x7fffffff;
}
int successor(int target)
{
    int res=0;
    for(int i=root;i;i=child[i][target>=BST[i]])
        if(target<BST[i])
            res=i;
    return res?BST[res]:0x7fffffff;
}
int main()
{
	read(n);
	for(int i=1;i<=n;++i)
	{
		read(opt);
        read(x);
		if(opt==1)
			insert(x);
		else if(opt==2)
			erase(x);
		else if(opt==3)
			printf("%d\n",rank_of(x));
		else if(opt==4)
			printf("%d\n",at(x));
		else if(opt==5)
			printf("%d\n",predecessor(x));
		else printf("%d\n",successor(x));
	}
	return 0;
}
2021/3/15 17:41
加载中...