同余方程 欧拉互质同余定理 质数筛 求约数 欧拉函数 转10x方转化 T4 https://www.acwing.com/problem/content/description/204/

 是中国的幸运数字,如果一个数字的每一位都由  构成则该数字被称作是幸运数字。

现在给定一个正整数 ,请问至少多少个  连在一起组成的正整数(即最小幸运数字)是  的倍数。

输入格式

输入包含多组测试用例。

每组测试用例占一行,包含一个整数 

当输入用例  时,表示输入终止,该用例无需处理。

输出格式

每组测试用例输出结果占一行。

结果为 Case i:+一个整数  代表满足条件的最小幸运数字的位数。

如果满足条件的幸运数字不存在,则 

数据范围

输入样例:

8
11
16
0

输出样例:

Case 1: 1
Case 2: 2
Case 3: 0

2 3 4 5 6 7 8 9 2 9 4 9 5 9 7 9 8 9

思路

给一个 L, 有可能存在 ,即多个8组成关于L的倍数。

x个8组成的数无论是存longlong还是用字符串都很麻烦, 考虑用一个公式来表示: x个1 再用 9表示 1: 分子又可以用减法表示: 至此就有一个更好处理的形式。接下来就是求:中满足条件的最小的x。

分母可以移过去:

因为 都是常数, 而我们只是要求整除的情况, 可以把两者的最大公因子筛去, 这样就能去掉右边的8: (d为 )。

式子左边设为常数 C, 那么就转化为: 求最小的正整数 x。

根据欧拉定理 , 其中 , a与n互质, 满足这个条件的话等式成立。 对应到当前的题目就是当 10 和 C 不互质的时候无解。若互质, 则解就是

但这个解并不一定是最小正整数解。

有一个结论, 所有满足同余方程的正整数解x一定满足 , 一定是 的约数。

的约数很少, 直接枚举就行。

代码

#include <bits/stdc++.h>
using namespace std;
 
typedef long long LL;
 
LL L;
 
LL qmul(LL a, LL b, LL p)
{
    LL res = 0;
    while (b)
    {
        if (b & 1)
            res = (res + a) % p;
        a = (a + a) % p;
        b >>= 1;
    }
    return res;
}
 
LL qmi(LL a, LL b, LL p)
{
    LL res = 1;
    while (b)
    {
        if (b & 1)
            res = qmul(res, a, p);
        a = qmul(a, a, p);
        b >>= 1;
    }
    return res;
}
 
LL gcd(LL a, LL b)
{
    return b ? gcd(b, a % b) : a;
}
 
LL get_eurl(LL c)
{
    LL res = c;
 
    for (int i = 2; i <= c / i; i++)
    {
        if (c % i == 0)
        {
            while (c % i == 0)
                c /= i;
            res = res / i * (i - 1);
        }
    }
    if (c > 1)
        res = res / c * (c - 1);
    return res;
}
 
void solve()
{
    LL d = gcd(L, 8);
    LL c = L * 9 / d;
 
    if (c % 2 == 0 || c % 5 == 0)
    {
        cout << 0 << endl;
        return;
    }
    // cout << c << endl;
    LL phi = get_eurl(c);
    // cout << phi << endl;
 
    LL res = 1e18;
    for (LL i = 1; i <= phi/i; i++)
    {
        if (phi % i == 0)
        {
            if (qmi(10, i, c) == 1)
                res = min(res, i);
            if (qmi(10, phi / i, c) == 1)
                res = min(res, phi / i);
        }
    }
    cout << res << endl;
}
 
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int kase = 1;
    while (cin >> L, L)
    {
        cout << "Case " << kase++ << ": ";
        solve();
    }
    return 0;
}