萌新刚学treap,48pts求调
查看原帖
萌新刚学treap,48pts求调
65924
Crystron_Halqifibrax楼主2022/9/12 18:38

rt,最后一点T其他错误WA

#include<bits/stdc++.h>
using namespace std;
const int Maxv=2147483647,Maxn=100005;
int ls[Maxn],rs[Maxn],fa[Maxn],v1[Maxn],v2[Maxn],siz[Maxn],num[Maxn];
int cnt,root=1,t;
inline void read(int &x)
{
	x=0;
	int f=1;
	char ch=getchar();
	while(ch<'0'||ch>'9')
	{
		if(ch=='-')
			f=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9')
	{
		x=(x<<1)+(x<<3)+(ch-48);
		ch=getchar();
	}
	x*=f;
}
void write(int x)
{
    if(x<0)
        putchar('-'),x=-x;
    if(x>9)
        write(x/10);
    putchar(x%10+'0');
    return;
}
inline void rrs(int x,int y)
{
	if(y==root)
		root=x;
	if(y==ls[fa[y]])
		ls[fa[y]]=x;
	else
		rs[fa[y]]=x;
	siz[x]=siz[y];
	siz[y]=siz[rs[x]]+siz[rs[y]]+1;
	fa[x]=fa[y];
	fa[y]=x;
	fa[rs[x]]=y;
	ls[y]=rs[x];
	rs[x]=y;
	
}
inline void lrs(int x,int y)
{
	if(y==root)
		root=x;
	if(y==ls[fa[y]])
		ls[fa[y]]=x;
	else
		rs[fa[y]]=x;
	siz[x]=siz[y];
	siz[y]=siz[ls[x]]+siz[ls[y]]+1;
	fa[x]=fa[y];
	fa[y]=x;
	fa[ls[x]]=y;
	rs[y]=ls[x];
	ls[x]=y;
}
void revolve(int now)
{
	if(!fa[now])
		return;
	if(v2[now]<v2[fa[now]]&&now==ls[fa[now]])
		rrs(now,fa[now]);
	if(v2[now]<v2[fa[now]]&&now==rs[fa[now]])
		lrs(now,fa[now]);
}
inline void pushup(int now)
{
	siz[now]=siz[ls[now]]+siz[rs[now]]+num[now];
}
void add(int now,int x)
{
	if(!now)
		return;
	if(x==v1[now])
		num[now]++,pushup(now);
	if(x<v1[now])
	{
		if(!ls[now])
		{
			ls[now]=cnt;
			fa[ls[now]]=now;
			v1[ls[now]]=x;
			v2[ls[now]]=rand();
			num[ls[now]]++;

			siz[ls[now]]++;
			siz[now]++;
		}
		else
			add(ls[now],x),pushup(now);
	}
	if(x>v1[now])
	{
		if(!rs[now])
		{
			rs[now]=cnt;
			fa[rs[now]]=now;
			v1[rs[now]]=x;
			v2[rs[now]]=rand();
			num[rs[now]]++;
			siz[rs[now]]++;
			siz[now]++;
		}
		else
			add(rs[now],x),pushup(now);
	}
}
int findno(int now,int x)
{
	if(!now)
		return 0;
	if(x==v1[now])
		return siz[ls[now]]+1;//x数是当前节点
	else if (x<v1[now]) 
		return findno(ls[now],x);//x在左子树内
	else 
		return siz[ls[now]]+num[now]+findno(rs[now],x);//右子树内,排名加上左子树和当前节点
}
int findx(int now,int x)
{	
	if(!now)
		return Maxv;
	if(x<=siz[ls[now]])
		findx(ls[now],x);//左子树
	else if(x<=siz[ls[now]]+num[now])
		return v1[now];//大于左子树小于与当前节点的和
	else
		findx(rs[now],x-siz[ls[now]]-num[now]);//右子树,排名减去当前节点、左子树
	
}
inline int findmax(int x)
{
	int t1=root,t2;
	while(t1)
	{
		if(v1[t1]<x)
		{
			t2=t1;
			t1=rs[t1];
		}
		else
			t1=ls[t1];
	}
	return v1[t2];
}
inline int findmin(int x)
{
	int t1=root,t2;
	while(t1)
	{
		if(v1[t1]>x)
		{
			t2=t1;
			t1=ls[t1];
		}
		else
			t1=rs[t1];
	}
	return v1[t2];
}

void leaf(int now)
{
	if((!ls[now])&&(!rs[now]))
		return;
	if(v2[ls[now]]<v2[rs[now]])
		rrs(ls[now],now);
	else
		lrs(rs[now],now);
	leaf(now);
}
void kil(int now,int x)
{
	if(!now)
		return;
	if(x==v1[now])
	{
		t=now;
		if(num[now]>1)
		{
			num[now]--;
			while(t)
				siz[t]--,t=fa[t];
			return;
		}
		leaf(now);
		while(t)
			siz[t]--,t=fa[t];
		if(now==ls[fa[now]])
			ls[fa[now]]=0;
		else
			rs[fa[now]]=0;
		num[now]--,ls[now]=rs[now]=fa[now]=0;
		return;
	}
	if(x<v1[now])
		kil(ls[now],x);
	else
		kil(rs[now],x);
}

int main()
{
	//freopen("P3369_6.in","r",stdin);
	//freopen("3.txt","w",stdout);
	int n,x,op;
	read(n);
	ls[0]=1,rs[0]=1,v1[0]=Maxv;
	for(int i=0;i<=n;i++)
		v1[i]=-Maxv,v2[i]=Maxv;
	for(int i=1;i<=n;i++)
	{
		read(op),read(x);
		if(op==1)
		{
			++cnt;
			if(cnt==1)
				v1[1]=x,v2[1]=rand(),siz[1]=1,fa[1]=0,num[1]=1;
			else
				add(root,x);
			revolve(cnt);
			//for(int i=1;i<=cnt;i++)
			//    printf("%d %d %d %d %d %d %d %d %d\n",root,i,ls[i],rs[i],fa[i],v1[i],v2[i],siz[i],num[i]);
		}
		if(op==2)
			kil(root,x);
		if(op==3)
			write(findno(root,x)),putchar('\n');
		if(op==4)
			write(findx(root,x)),putchar('\n');
		if(op==5)
			write(findmax(x)),putchar('\n');
		if(op==6)
			write(findmin(x)),putchar('\n');
	}
	//for(int i=1;i<=cnt;i++)
	//	if(num[i]>1)	printf("%d\n",i);
	return 0;
}

2022/9/12 18:38
加载中...