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

LostKeyToReach
争取今年不退役 || int_stl. || 有意互关私。搬运于
2025-08-24 22:58:33,当前版本为作者最后更新于2024-05-17 10:17:39,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
upd:修改了时间复杂度。
这是一道数论好题,我介绍一下蓝书的做法。
不难发现, 个 连起来的正整数等价于 ,那么题目转换为,给出 ,让我们求一个最小的正整数 ,使得:
我们先把两边乘上 ,得:
我们不妨再设 ,又可以把原式化为:
再改写为同余式:
此时,我们再引入一个引理:若 互质,则满足 的最小正整数解为 的约数。
证明过程(摘录自蓝书):
反证法。假设满足 的最小正整数解 不能整除 。
设 。因为 ,所以 。根据欧拉定理,有 ,所以 。这与 最小矛盾,故假设不成立,原命题成立。
证毕。
那么我们就可以轻松地解决这道题了,根据引理,我们先求出 ,然后枚举它的所有约数 ,当 时,直接输出即可。
如何判断无解呢?只需判断 是否不等于 即可。
这样,我们就完成了这道题目,时间复杂度 (排序后)。
主体部分代码如下:
vector <ll> t; ll phi(ll x) { ll ans = x; for (int i = 2; i * i <= x; i++) { if (x % i == 0) { ans = ans * (i - 1) / i; while (x % i == 0) x /= i; } } if (x > 1) ans = ans * (x - 1) / x; return ans; } int main() { ll n; int cnt = 0; while (read(n), n) { t.clear(); n = 9 * n / gcd(n, 8ll); cout << "Case " << ++cnt << ": "; if (gcd(n, 10ll) != 1) { cout << "0\n"; } else { ll x = phi(n); for (ll i = 1; i * i <= x; i++) { if (x % i == 0) { t.push_back(i); if (x / i != i) { t.push_back(x / i); } } } sort(t.begin(), t.end()); int i; for (i = 0; i < t.size(); i++) { if (quick_pow(10ll, t[i], n) == 1) { break; } } writeln(t[i]); } } }
- 1
信息
- ID
- 10252
- 时间
- 1000ms
- 内存
- 512MiB
- 难度
- 5
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者