Luogu P11132 【MX-X5-T4】「GFOI Round 1」epitaxy 题解

P11132 【MX-X5-T4】「GFOI Round 1」epitaxy

基于次大值的构造。

考虑到如果最大值和次大值都出现那么结果一定为 1。而如果次大值在序列中出现 2m1 次,则一定会与最大值一起出现,这是不好的。

因此,我们构造把次大值放在序列开头,之后最大值必须要放在前 m 个位置。这中间有 m2 个空位,我们填上 n2nm1,剩下的位置需要填入一个 1nm 的排列,这是一个完全相同的子问题。

如果我们不把空位填上 n2nm1,就是希望能更改答案序列中的值。而这种更改上述构造方式也能做到,所以直接这样构造是没有问题的。另外,也可以把次大值放在序列结尾,但是只是改变一个方向,本质相同。如果不把次大值贴紧开头,与这个构造也是等价的,但变得不好处理。

我们发现答案序列中的数构成等差序列且公差为 n 的约数时才能更新答案,所以我们枚举公差,按照上述方式构造即可。

注意有可能 m 过大,最小值不能出现 2m1 次,这个时候把最大值放中间就好了。我因为这个边界条件卡了一整场,警示后人。

#include <bits/stdc++.h>
using namespace std;
long long t,n,m,ans=0;
int main()
{
	scanf("%lld",&t);
	while(t--)
	   {
	   	scanf("%lld%lld",&n,&m);
	   	if(m>n/2)
	   	   {
	   	   	for(int i=1;i<=n/2;i++)printf("%lld ",1ll*i);
	   	   	printf("%lld ",n);
	   	   	for(int i=n/2+2;i<=n;i++)printf("%lld ",i-1ll);
		   }
	   	else
		   	{
		   	bool flag=1;
			for(int i=m;i>=2;i--)
			   	if(n%i==0)
			   	    {
			   	    long long now=n;
			   	    flag=0;
				   	while(now>0)
				   	    {
				   	    printf("%lld ",now-1);
				   	    for(int j=1;j<=i-2;j++)printf("%lld ",now-1-j);
				   	    printf("%lld ",now);
				   	    now-=i;
						}
					break;
					}
			if(flag)for(int i=1;i<=n;i++)printf("%lld ",i);
		    }
		printf("\n");
	   }
	return 0;
}
posted @   w9095  阅读(2)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
点击右上角即可分享
微信分享提示