vector的Splay49pts求条
查看原帖
vector的Splay49pts求条
1163238
YWHHDJSer楼主2024/7/9 10:51

RT。

#include<bits/stdc++.h>
using namespace std;
#define il inline
#define ri register int
struct Splay
{
	int root,cnt;
	vector<int>fa,val,siz,sons[2],num;
	il void pre()
	{
		fa.push_back(0);
		val.push_back(0);
		siz.push_back(0);
		sons[1].push_back(0);
		sons[0].push_back(0);
		num.push_back(0);
	}
	il void pu(int x)
	{
		siz[x]=siz[sons[0][x]]+siz[sons[1][x]]+num[x];
	}
	il void esc(int x)
	{
		fa[x]=0;
		siz[x]=0;
		sons[0][x]=0;
		sons[1][x]=0;
		val[x]=0;
		num[x]=0;
	}
	il int faso(int x)
	{
		return sons[0][fa[x]]==x?0:1;
	}
	il void rota(int x)
	{
		int y=fa[x],z=fa[y],pl=faso(x);
		sons[pl][y]=sons[pl^1][x];
		if(sons[pl^1][x]!=0)
		{
			fa[sons[pl^1][x]]=y;
		}
		sons[pl^1][x]=y;
		fa[y]=x;
		fa[x]=z;
		if(z!=0)
		{
			pl=(y==sons[0][z]?0:1);
			sons[pl][z]=x;
		}
		pu(y);
		pu(x);
		return;
	}
	il void splay(int x,int y)
	{
		if(y==0)
		{
			root=x;
		}
		while(fa[x]!=y)
		{
			int u=fa[x],v=fa[u];
			if(v!=y)
			{
				int pl=(faso(x)==faso(u)?u:x);
				rota(pl);
			}
			rota(x);
		}
		return;
	}
	il void push(int x)
	{
		if(root==0)
		{
			cnt++;
			val.push_back(x);
			num.push_back(1);
			fa.push_back(0);
			siz.push_back(0);
			root=cnt;
			sons[0].push_back(0);
			sons[1].push_back(0);
			pu(root);
			return;
		}
		int pl=root,y=0;
		while(1==1)
		{
			if(val[pl]==x)
			{
				num[pl]++;
				pu(pl);
				pu(y);
				splay(pl,0); 
				return;
			}
			y=pl;
			val[pl]<x?pl=sons[1][pl]:pl=sons[0][pl];
			if(pl==0)
			{
				cnt++;
				val.push_back(x);
				num.push_back(1);
				fa.push_back(y);
				sons[0].push_back(0);
				sons[1].push_back(0);
				val[y]<x?sons[1][y]=cnt:sons[0][y]=cnt;
				pu(cnt);
				pu(y);
				splay(cnt,0);
				return;
			}
		}
	}
	il int renk(int x)
	{
		int rn=0,pl=root;
		while(1==1)
		{
			if(x<val[pl])
			{
				pl=sons[0][pl];
				continue;
			}
			rn+=siz[sons[0][pl]];
			if(pl==0)
			{
				rn++;
				return rn;
			}
			if(x==val[pl])
			{
				splay(pl,0);
				rn++;
				return rn;
			}
			rn+=num[pl];
			pl=sons[1][pl];
		}
	}
	il void pop(int x)
	{
		int z=renk(x);
		if(num[root]>1)
		{
			num[root]--;
			pu(root);
			return;
		}
		if(sons[0][root]==0&&sons[1][root]==0)
		{
			esc(root);
			root=0;
			return;
		}
		int pl=root;
		if(sons[0][root]==0)
		{
			root=sons[1][root];
			fa[root]=0;
			esc(pl);
			return;
		}
		if(sons[1][root]==0)
		{
			root=sons[0][root];
			fa[root]=0;
			esc(pl);
			return;
		}
		int y;
		if(sons[0][root]==0)
		{
			y=root;
		}
		y=sons[0][root];
		while(sons[1][y]!=0)
		{
			y=sons[1][y];
		}
		splay(y,0);
		fa[sons[1][pl]]=y;
		sons[1][y]=sons[1][pl];
		esc(pl);
		pu(root);
	}
	il int thnk(int x)
	{
		if(x>cnt)
		{
			return 0;
		}
		int pl=root;
		while(1==1)
		{
//			printf("**%d**\n",pl);
			if(sons[0][pl]!=0&&x<=siz[sons[0][pl]])
			{
				pl=sons[0][pl];
				continue;
			}
			x-=siz[sons[0][pl]];
			if(x<=num[pl])
			{
				splay(pl,0);
				return val[pl];
			}
			x-=num[pl];
			pl=sons[1][pl];
		}
	}
	il int front(int x)
	{
		(*this).push(x);
		if(num[root]>1)
		{
			(*this).pop(x);
			return val[root];
		}
		if(sons[0][root]==0)
		{
			return 0;
		}
		int pl=sons[0][root],rn;
		while(sons[1][pl]!=0)
		{
			pl=sons[1][pl];
		}
		rn=val[pl];
		splay(pl,0);
		(*this).pop(x);
		return rn;
	}
	il int back(int x)
	{
		(*this).push(x);
		if(num[root]>1)
		{
			(*this).pop(x);
			return val[root];
		}
		if(sons[1][root]==0)
		{
			return 0;
		}
		int pl=sons[1][root],rn;
		while(sons[0][pl]!=0)
		{
			pl=sons[0][pl];
		}
		rn=val[pl];
		splay(pl,0);
		(*this).pop(x);
		return rn;
	}
	il int begin()
	{
		int pl=root;
		while(sons[0][pl]!=0)
		{
			pl=sons[pl][0];
		}
		return val[pl];
	}
	il int end()
	{
		int pl=root;
		while(sons[1][pl]!=0)
		{
			pl=sons[pl][1];
		}
		return val[pl];
	}
}tree;
int a,u,in;
int main()
{
	freopen("in.txt","r",stdin);
	tree.pre();
	tree.push(0x3f3f3f3f);
	tree.push(-0x3f3f3f3f);
	scanf("%d",&a);
//	while(a--)
	for(int i=1;i<=a;i++)
	{
		printf("-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=%d\n",i);
		scanf("%d%d",&in,&u);
		if(in==1)
		{
			tree.push(u);
			continue;
		}
		if(in==2)
		{
			tree.pop(u);
			continue;
		}
		if(in==3)
		{
			printf("%d\n",tree.renk(u)-1);
			continue;
		}
		if(in==4)
		{
			printf("%d\n",tree.thnk(u+1));
			continue;
		}
		if(in==5)
		{
			printf("%d\n",tree.front(u));
			continue;
		}
		if(in==6)
		{
			printf("%d\n",tree.back(u));
			continue;
		}
	}
	return 0;
}
/*
10
1 106465
4 1
1 317721
1 460929
1 644985
1 84185
1 89851
6 81968
1 492737
5 493598

106465
84185
492737
*/

AC on 1&2&3&4&5&6&13,WA on 11&14,RE on 8,TLE on 7&9&10&12.

代码原型是之前用数组A过的代码。 原来的代码:

#include<bits/stdc++.h>
using namespace std;
#define il inline
#define ri register
struct node0
{
	int fa,val,num,siz,sons[2];
}tree[400004];
int root,cnt,a,u,in;
il void pu(int x)
{
	tree[x].siz=tree[tree[x].sons[0]].siz+tree[tree[x].sons[1]].siz+tree[x].num;
}
il void esc(int x)
{
	tree[x].fa=tree[x].num=tree[x].siz=tree[x].sons[0]=tree[x].sons[1]=tree[x].val=0;
}
il int faso(int x)
{
	return tree[tree[x].fa].sons[0]==x?0:1;
}
il void rota(int x)
{
	int y=tree[x].fa,z=tree[y].fa,pl=faso(x);
	tree[y].sons[pl]=tree[x].sons[pl^1];
	if(tree[x].sons[pl^1]!=0)
	{
		tree[tree[x].sons[pl^1]].fa=y;
	}
	tree[x].sons[pl^1]=y;
	tree[y].fa=x;
	tree[x].fa=z;
	if(z!=0)
	{
		pl=(y==tree[z].sons[0]?0:1);
		tree[z].sons[pl]=x;
	}
	pu(y);
	pu(x);
	return;
}
il void splay(int x,int y)
{
	if(y==0)
	{
		root=x;
	}
	while(tree[x].fa!=y)
	{
		int u=tree[x].fa,v=tree[u].fa;
		if(v!=y)
		{
			int pl=(faso(x)==faso(u)?u:x);
			rota(pl);
		}
		rota(x);
	}
	return;
}
il void push(int x)
{
	if(root==0)
	{
		cnt++;
		tree[cnt].val=x;
		tree[cnt].num++;
		root=cnt;
		pu(root);
		return;
	}
	int pl=root,y=0;
	while(1==1)
	{
		if(tree[pl].val==x)
		{
			tree[pl].num++;
			pu(pl);
			pu(y);
			splay(pl,0); 
			return;
		}
		y=pl;
		tree[pl].val<x?pl=tree[pl].sons[1]:pl=tree[pl].sons[0];
		if(pl==0)
		{
			cnt++;
			tree[cnt].val=x;
			tree[cnt].num++;
			tree[cnt].fa=y;
			tree[y].val<x?tree[y].sons[1]=cnt:tree[y].sons[0]=cnt;
			pu(cnt);
			pu(y);
			splay(cnt,0);
			return;
		}
	}
}
il int renk(int x)
{
	int rn=0,pl=root;
	while(1==1)
	{
		if(x<tree[pl].val)
		{
			pl=tree[pl].sons[0];
			continue;
		}
		rn+=tree[tree[pl].sons[0]].siz;
		if(pl==0)
		{
			rn++;
			return rn;
		}
		if(x==tree[pl].val)
		{
			splay(pl,0);
			rn++;
			return rn;
		}
		rn+=tree[pl].num;
		pl=tree[pl].sons[1];
	}
}
il int thnk(int x)
{
	int pl=root;
	while(1==1)
	{
		if(tree[pl].sons[0]!=0&&x<=tree[tree[pl].sons[0]].siz)
		{
			pl=tree[pl].sons[0];
			continue;
		}
		x-=tree[tree[pl].sons[0]].siz;
		if(x<=tree[pl].num)
		{
			splay(pl,0);
			return tree[pl].val;
		}
		x-=tree[pl].num;
		pl=tree[pl].sons[1];
	}
}
il int front(int x)
{
	if(tree[root].sons[0]==0)
	{
		return root;
	}
	int pl=tree[root].sons[0],rn;
	while(tree[pl].sons[1]!=0)
	{
		pl=tree[pl].sons[1];
	}
	rn=tree[pl].val;
	splay(pl,0);
	return rn;
}
il int back(int x)
{
	if(tree[root].sons[1]==0)
	{
		return root;
	}
	int pl=tree[root].sons[1],rn;
	while(tree[pl].sons[0]!=0)
	{
		pl=tree[pl].sons[0];
	}
	rn=tree[pl].val;
	splay(pl,0);
	return rn;
}
il int begin()
{
	int x=root;
	while(tree[x].sons[0]!=0)
	{
		x=tree[x].sons[0];
	}
	splay(x,0);
	return tree[x].val;
}
il int end()
{
	int x=root;
	while(tree[x].sons[1]!=0)
	{
		x=tree[x].sons[1];
	}
	splay(x,0);
	return tree[x].val;
}
il void pop(int x)
{
	int z=renk(x);
	if(tree[root].num>1)
	{
		tree[root].num--;
		pu(root);
		return;
	}
	if(tree[root].sons[0]==0&&tree[root].sons[1]==0)
	{
		esc(root);
		root=0;
		return;
	}
	int pl=root;
	if(tree[root].sons[0]==0)
	{
		root=tree[root].sons[1];
		tree[root].fa=0;
		esc(pl);
		return;
	}
	if(tree[root].sons[1]==0)
	{
		root=tree[root].sons[0];
		tree[root].fa=0;
		esc(pl);
		return;
	}
	int y;
	if(tree[root].sons[0]==0)
	{
		y=root;
	}
	y=tree[root].sons[0];
	while(tree[y].sons[1]!=0)
	{
		y=tree[y].sons[1];
	}
	splay(y,0);
	tree[tree[pl].sons[1]].fa=y;
	tree[y].sons[1]=tree[pl].sons[1];
	esc(pl);
	pu(root);
}
int main()
{
//	freopen("A.in","r",stdin);
	push(0x3f3f3f3f);
	push(-0x3f3f3f3f);
	scanf("%d",&a);
	while(a--)
	{
		scanf("%d%d",&in,&u);
		if(in==1)
		{
			push(u);
			continue;
		}
		if(in==2)
		{
			pop(u);
			continue;
		}
		if(in==3)
		{
			printf("%d\n",renk(u)-1);
			continue;
		}
		if(in==4)
		{
			printf("%d\n",thnk(u+1));
			continue;
		}
		if(in==5)
		{
			push(u);
			printf("%d\n",front(u));
			pop(u);
			continue;
		}
		if(in==6)
		{
			push(u);
			printf("%d\n",back(u));
			pop(u);
			continue;
		}
	}
	return 0;
}
/*
10
1 106465
4 1
1 317721
1 460929
1 644985
1 84185
1 89851
6 81968
1 492737
5 493598

*/

希望有dalao可以指出问题。

2024/7/9 10:51
加载中...