1 条题解
-
0
自动搬运
来自洛谷,原作者为

EuphoricStar
Remember.搬运于
2025-08-24 23:04:31,当前版本为作者最后更新于2024-09-29 15:40:28,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
首先若 最大价值就是 ,一个答案是:
否则最大价值是 的最大的 的因数,设其为 。一个答案是:
$$1 \sim d, 2d, d + 1 \sim 2d - 1, \ldots, n, n - d + 1 \sim n - 1 $$最大价值是 的证明:
显然一个排列的价值是 的因数。因为前面已经给出了一个最大价值为 的构造,所以只需要证 的 的因数不可能成为一个排列的价值。
任取 的一个 的因数,设其为 。那么首先每个长度为 的子段都一定要有一个 的倍数。
若一个 的倍数 是一个长度为 的子段的最大值,就称 支配了这个子段。
可以发现 最多只能支配 个子段,还剩下 个子段需要支配。
显然一个数至多支配 个子段,剩下的 的倍数有 个。
因为 $(\frac{n}{x} - 1) \times m < (\frac{n}{x} - 1) \times x = n - x$,所以这些数不可能支配所有长度为 的子段。
时间复杂度:每个测试用例 。
#include <bits/stdc++.h> #define pb emplace_back #define fst first #define scd second #define mkp make_pair #define mems(a, x) memset((a), (x), sizeof(a)) using namespace std; typedef long long ll; typedef double db; typedef unsigned long long ull; typedef long double ldb; typedef pair<ll, ll> pii; void solve() { int n, m; scanf("%d%d", &n, &m); if (m * 2 > n) { for (int i = 1; i <= n; ++i) { int x = i; if (i == m) { x = n; } else if (i > m) { --x; } printf("%d%c", x, " \n"[i == n]); } } else { while (n % m) { --m; } for (int i = 1; i <= n; ++i) { int t = i; if (i > m && (i - 1) % m == 0) { t += m - 1; } else if (i > m) { --t; } printf("%d%c", t, " \n"[i == n]); } } } int main() { int T = 1; scanf("%d", &T); while (T--) { solve(); } return 0; }闲话:这题一开始是 MX-X only 的 T1。
- 1
信息
- ID
- 10659
- 时间
- 2000ms
- 内存
- 512MiB
- 难度
- 4
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者