最幸运的数 (同余+欧拉定理)

最幸运的数

[LInk](202. 最幸运的数字 - AcWing题库)

题意

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

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

题解

​ 将题目转化为数学符号的形式即找到最小的 x x x满足 L ∣ 8 ( 1 0 x − 1 ) 9 L\mid \frac{8(10^{x}-1)}{9} L∣98(10x−1)​

即 9 L ∣ 8 ( 1 0 x − 1 ) 9L\mid8(10^x-1) 9L∣8(10x−1) ,设 d = g c d ( L , 8 ) d=gcd(L,8) d=gcd(L,8), 则 9 L d ∣ 8 d ( 1 0 x − 1 ) \frac{9L}{d}\mid\frac{8}{d}(10^x-1) d9L​∣d8​(10x−1), d d d是 9 L 和 8 9L和8 9L和8的最大公约数,因此 ( 9 L 8 , 8 d ) = = 1 (\frac{9L}{8},\frac{8}{d})==1 (89L​,d8​)==1,所以如果满足整除则应该

9 L 8 ∣ ( 1 0 x − 1 ) \frac{9L}{8}\mid(10^x-1) 89L​∣(10x−1),设 n = 9 L 8 n=\frac{9L}{8} n=89L​,则 9 L 8 ∣ ( 1 0 x − 1 ) → 1 0 x ≡ 1 ( m o d   n ) \frac{9L}{8}\mid(10^x-1)\rightarrow 10^x\equiv1(mod\ n) 89L​∣(10x−1)→10x≡1(mod n)。

欧拉定理

若(a,n)==1,则 a φ ( n ) ≡ 1 ( m o d   n ) a^{\varphi(n)}\equiv1(mod\ n) aφ(n)≡1(mod n)

发现我们要求的最小的 x x x一定是 φ ( n ) \varphi(n) φ(n)的一个约数

证明

假设存在一个最小的不是 φ ( n ) \varphi(n) φ(n)的约数解x,则 φ ( n ) = a x + r 且 0 < r < x \varphi(n)=ax+r且0<r<x φ(n)=ax+r且0<r<x

a x ≡ 1 ( m o d   n ) → a a x ≡ 1 ( m o d   n ) a^x\equiv1(mod\ n)\rightarrow a^{ax}\equiv1(mod\ n) ax≡1(mod n)→aax≡1(mod n)

a φ ( n ) ≡ 1 ( m o d   n ) → a a x + r ≡ 1 ( m o d   n ) → a r ≡ 1 ( m o d   n ) a^{\varphi(n)}\equiv1(mod\ n)\rightarrow a^{ax+r}\equiv1(mod\ n)\rightarrow a^r\equiv1(mod\ n) aφ(n)≡1(mod n)→aax+r≡1(mod n)→ar≡1(mod n)

有 r < x r<x r<x所以找到了一个更小的解,与假设矛盾因子,最小的解一定是 φ ( n ) \varphi(n) φ(n)的约数

因此找出 φ ( n ) \varphi(n) φ(n)的所有约数,判断一下是否成立即可,因为数据太大会爆 L L LL LL因此要用龟速乘

Code

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <set>
#include <queue>
#include <vector>
#include <map>
#include <bitset>
#include <unordered_map>
#include <cmath> 
#include <stack>
#include <iomanip>
#include <deque> 
#include <sstream>
#define x first
#define y second
#define debug(x) cout<<#x<<":"<<x<<endl;
using namespace std;
typedef long double ld;
typedef long long LL;
typedef pair<int, int> PII;
typedef pair<double, double> PDD;
typedef unsigned long long ULL;
const int N = 1e5 + 10, M = 2 * N, INF = 0x3f3f3f3f, mod = 1e9 + 7;
const double eps = 1e-8, pi = acos(-1), inf = 1e20;
#define tpyeinput int
inline char nc() {static char buf[1000000],*p1=buf,*p2=buf;return p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++;}
inline void read(tpyeinput &sum) {char ch=nc();sum=0;while(!(ch>='0'&&ch<='9')) ch=nc();while(ch>='0'&&ch<='9') sum=(sum<<3)+(sum<<1)+(ch-48),ch=nc();}
int dx[] = {-1, 0, 1, 0}, dy[] = {0, 1, 0, -1};
int h[N], e[M], ne[M], w[M], idx;
void add(int a, int b, int v = 0) {
    e[idx] = b, w[idx] = v, ne[idx] = h[a], h[a] = idx ++;
}
LL L;
LL gcd(LL a, LL b) {
    return b ? gcd(b, a % b) : a;
}
LL mul(LL a, LL b, LL p) {
    LL res = 0;
    while (b) {
        if (b & 1) res = (res + a) % p;
        a = (a * 2) % p;
        b >>= 1;
    }
    return res;
}
LL qmi(LL a, LL b, LL p) {
    LL res = 1;
    while (b) {
        if (b & 1) res = mul(res, a, p);
        a = mul(a, a, p);
        b >>= 1;
    }
    return res;
}
LL get_phi(LL x) {
    LL res = x;
    for (int i = 2; i <= x / i; i ++ ) {
        if (x % i == 0) {
            while (x % i == 0) x /= i;
            res = res / i * (i - 1);
        }
    }
    if (x > 1) res = res / x * (x - 1);
    return res;
}
int main() {
    int id = 0;
    while (cin >> L, L) {
        LL n = 9 * L / gcd(8, L);
        LL phi = get_phi(n);
        if (gcd(10, n) != 1) {
            printf("Case %d: %lld\n", ++id, 0);
            continue ;
        }
        LL res = 1e18;
        for (LL i = 1; i <= phi / i; i ++ ) {
            if (phi % i == 0) {
                if (qmi(10, i, n) == 1) res = min(res, i);
                if (qmi(10, phi / i, n) == 1) res = min(res, phi / i);
            }
        }
        printf("Case %d: %lld\n", ++id, res);
    }
    return 0;
}
上一篇:Codeforces 269B.Greenhouse Effect(lis水题)


下一篇:CentOS 7下安装samba