Luogu P5462 X龙珠|贪心

题目链接

首先题目要求字典序最大,则显然我们应该将大的数安排在前端。

那么现在来处理取相邻数的问题,我们可以使用并查集维护 每个位置往后最近的未被取走的数的位置,下文用\(fa_i\)表示。

当一个数(假定位置为\(i\))被取走时,将\(fa_i=fa_{i+1}\),查询时直接取出即可。

另外,当要取的数是最后一个时,后面没数,不合题意。需要特判。

上代码

#include<bits/stdc++.h>
using namespace std;
int n,m;int a[100500],fa[100500],ans[100500],b[100500];
//b数组存每个数的出现位置
int fafa(int x)
{
	if (fa[x]==x) return x;
	return fa[x]=fafa(fa[x]);
}
void hebing(int x,int y)
{
	x=fafa(x);y=fafa(y);
	fa[x]=y;
}
//并查集维护上文所述
int main()
{
	cin>>n;
	for (int i=1;i<=n;i++)
	{
		cin>>a[i];
		b[a[i]]=i;
		fa[i]=i;
	}
	for (int i=n;i>0;i--)
	{
		if (fa[b[i]]==b[i]&&fafa(b[i]+1)!=0&&b[i]!=n)//特判,fafa(b[i]+1)=0代表后面没数
		{
			ans[++m]=i;
			ans[++m]=a[fafa(b[i]+1)];
			hebing(b[i],fa[b[i]+1]);
			hebing(fa[b[i]+1],fafa(fa[b[i]+1]+1));
		}
	}
	for (int i=1;i<m;i++)
	{
		cout<<ans[i]<<" ";
	}
	cout<<ans[m];
	return 0;
}
posted @ 2019-07-15 21:56  fmj_123  阅读(148)  评论(0编辑  收藏  举报