题解:P10496 The Luckiest Number
LostKeyToReach · · 题解
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]);
}
}
}