萌新刚学OI,只AC了一个点,求助
查看原帖
萌新刚学OI,只AC了一个点,求助
382274
暗影之梦楼主2022/6/24 21:02

这一题这个萌新的思路好像很奇怪。。。

思路是先将每个书的编号与位置绑定,将位置当成权值,然后用fhq treap

置顶/置底操作就是先删除再以最小/最大的权值插入。每个插入的位置中间会有 8000080000 个空隙。

Insert操作则是先删除,将准备插入的位置设为 ii ,再将新数插到这个 i1i-1ii 的空隙里。

代码:

#include<iostream>
#include<cstdio>
#include<random>
#include<ctime>
#define int long long
using namespace std;
mt19937 rnd(time(0));
struct node
{
	int val,l,r,siz,key,id;
}fhq[160001];
int n,m,cnt,smax,smin,a[160001];
char op[10];
int ins(int nw,int val)
{
	fhq[++cnt].val=val;
	fhq[cnt].key=rnd();
	fhq[cnt].siz=1;
	fhq[cnt].id=nw;
	return cnt;
}
void upd(int nw)
{
	fhq[nw].siz=fhq[fhq[nw].l].siz+fhq[fhq[nw].r].siz+1;
}
void spl(int nw,int val,int &x,int &y)
{
	if(!nw) x=y=0;
	else
	{
		if(fhq[nw].val<=val)
		{
			x=nw;
			spl(fhq[nw].r,val,fhq[nw].r,y);
		}else
		{
			y=nw;
			spl(fhq[nw].l,val,x,fhq[nw].l);
		}
		upd(nw);
	}
}
int mer(int x,int y)
{
	if(!x||!y) return x+y;
	if(fhq[x].key<fhq[y].key)
	{
		fhq[x].r=mer(fhq[x].r,y);
		upd(x);
		return x;
	}else
	{
		fhq[y].l=mer(x,fhq[y].l);
		upd(y);
		return y;
	}
}
int x,y,z,root;
void inser(int id,int val)
{
	a[id]=val;
	spl(root,val,x,y);
	root=mer(mer(x,ins(id,val)),y);
}
void del(int val)
{
	spl(root,val,x,z);
	spl(x,val-1,x,y);
	y=mer(fhq[y].l,fhq[y].r);
	root=mer(mer(x,y),z);
}
int rnk(int val)
{
	spl(root,val-1,x,y);
	int ans=fhq[x].siz+1;
	root=mer(x,y);
	return ans;
}
int valu(int rnk)
{
	int nw=root;
	while(nw)
	{
		if(fhq[fhq[nw].l].siz+1==rnk) break;
		else if(fhq[fhq[nw].l].siz>=rnk) nw=fhq[nw].l;
		else
		{
			rnk-=fhq[fhq[nw].l].siz+1;
			nw=fhq[nw].r;
		}
	}
	return nw;
}
//void ccout(int nw,int fa)
//{
//	if(!nw) return;
//	cout<<nw<<" "<<fa<<" "<<fhq[nw].val<<" "<<fhq[nw].id<<endl;
//	ccout(fhq[nw].l,nw);
//	ccout(fhq[nw].r,nw);
//}
signed main()
{
	scanf("%lld%lld",&n,&m);
	smax=n+1;
	smin=-1;
	for(int i=1;i<=n;i++) 
	{
		int x;
		scanf("%lld",&x);
		inser(x,i*80000);
	}
//	ccout(root,0);
	for(int i=1;i<=m;i++)
	{
		scanf("%s",op+1);
		int s;
		scanf("%lld",&s);
//		ccout(root,0);
		if(op[1]=='T')
		{
			del(a[s]);
			inser(s,smin*80000);
			smin--;
		}else if(op[1]=='B')
		{
			del(a[s]);
			inser(s,smax*80000);
			smax++;
		}else if(op[1]=='I')
		{
			int t;
			scanf("%lld",&t);
			int nwrk=rnk(a[s]);
//			cout<<nwrk<<" "<<nwrk+t<<endl;
			nwrk+=t;
			nwrk--;
			int val=fhq[valu(nwrk)].val;
//			cout<<nwrk<<" "<<valu(nwrk)<<endl;
			del(a[s]);
			inser(s,val+1);
		}else if(op[1]=='A')
		{
//			cout<<n<<"gxrh"<<" "<<rnk(a[s])<<endl;
			printf("%lld\n",rnk(a[s])-1);
		}else
		{
			printf("%lld\n",fhq[valu(s)].id);
		}
	}
	return 0;
}
2022/6/24 21:02
加载中...