3 条题解
-
0
P11132 【MX-X5-T4】「GFOI Round 1」epitaxy
基于次大值的构造。
考虑到如果最大值和次大值都出现那么结果一定为 。而如果次大值在序列中出现 次,则一定会与最大值一起出现,这是不好的。
因此,我们构造把次大值放在序列开头,之后最大值必须要放在前 个位置。这中间有 个空位,我们填上 ,剩下的位置需要填入一个 的排列,这是一个完全相同的子问题。
如果我们不把空位填上 ,就是希望能更改答案序列中的值。而这种更改上述构造方式也能做到,所以直接这样构造是没有问题的。另外,也可以把次大值放在序列结尾,但是只是改变一个方向,本质相同。如果不把次大值贴紧开头,与这个构造也是等价的,但变得不好处理。
我们发现答案序列中的数构成等差序列且公差为 的约数时才能更新答案,所以我们枚举公差,按照上述方式构造即可。
注意有可能 过大,最小值不能出现 次,这个时候把最大值放中间就好了。我因为这个边界条件卡了一整场,警示后人。
#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; }
信息
- ID
- 69
- 时间
- 3000ms
- 内存
- 512MiB
- 难度
- 5
- 标签
- 递交数
- 446
- 已通过
- 92
- 上传者