其他分享
首页 > 其他分享> > The Luckiest number(同余+欧拉定理)

The Luckiest number(同余+欧拉定理)

作者:互联网

题目传送门

单词小讲堂

consist 组成
multiple 倍数
construct 构建,构造

题目大意

这个题的意思就是说,中国人认为8是吉祥数,当然了鲍勃有自己的吉祥数L,但是鲍勃喜欢中国女生,所以希望自己的吉祥数L的倍数可以是8888888……(n个8),下面给出一些L请你找出这些8的最小位数,如果不行,输出0即可!

思路

公式预警!!
考虑到 8888888 … … = ( 100000000000 … … − 1 ) ∗ 8 9 8888888……=(100000000000……-1)*\frac{8}{9} 8888888……=(100000000000……−1)∗98​
因此这道题就可以表示为 L ∣ 8 9 ∗ ( 1 0 y − 1 ) L|\frac{8}{9}*(10^y-1) L∣98​∗(10y−1)
9 L ∣ 8 ∗ ( 1 0 y − 1 ) 9L|8*(10^y-1) 9L∣8∗(10y−1)
两边同时除以 g c d ( 9 L , 8 ) gcd(9L,8) gcd(9L,8)
9 L g c d ( 9 L , 8 ) ∣ 8 g c d ( 9 L , 8 ) ∗ ( 1 0 y − 1 ) \frac{9L}{gcd(9L,8)}|\frac{8}{gcd(9L,8)}*(10^y-1) gcd(9L,8)9L​∣gcd(9L,8)8​∗(10y−1)
那么现在 9 L g c d ( 9 L , 8 ) 和 8 g c d ( 9 L , 8 ) \frac{9L}{gcd(9L,8)} 和\frac{8}{gcd(9L,8)} gcd(9L,8)9L​和gcd(9L,8)8​互质
因此 9 L g c d ( 9 L , 8 ) ∣ ( 1 0 y − 1 ) \frac{9L}{gcd(9L,8)}|(10^y-1) gcd(9L,8)9L​∣(10y−1)结果就是 y y y的最小值
为嘛?因为 8 g c d ( 9 L , 8 ) \frac{8}{gcd(9L,8)} gcd(9L,8)8​是小于 10 10 10的数,因此位数就是 y y y的值。
令 n = 9 L g c d ( 9 L , 8 ) n=\frac{9L}{gcd(9L,8)} n=gcd(9L,8)9L​
转化成为了 k ∗ n = 1 0 y − 1 k*n=10^y-1 k∗n=10y−1
啊,这不就是我们的同余公式嘛
1 0 y ≡ 1 ( m o d n ) 10^y≡1(mod n) 10y≡1(modn)
好了,现在我们只需要求 y y y的值就可以了!
下面我们介绍拓展欧拉定理的一个小结论

若正整数 a , n a,n a,n互质,则满足 a x ≡ 1 ( m o d n ) a^x≡1(mod n) ax≡1(modn)的最小正整数 x 0 x_0 x0​是 φ ( n ) φ(n) φ(n)的约数

那么我们现在逐一枚举 φ ( n ) φ(n) φ(n)的因子,就可以了。(需要快速幂优化)

#include<iostream>
#include<cmath>
using namespace std;
typedef long long ll;
ll phi(ll x)
{
    ll res = x;
    for (ll i = 2; i <= x / i; i ++ )
        if (x % i == 0)
        {
            res = res / i * (i - 1);
            while (x % i == 0) x /= i;
        }
    if (x > 1) res = res / x * (x - 1);

    return res;
}
ll gcd(ll a,ll b){
    return b?gcd(b,a%b):a;
}
ll qmi(ll m, ll k, ll p)
{
    ll res = 1 % p, t = m;
    while (k)
    {
        if (k&1) res = res * t % p;
        t = t * t % p;
        k >>= 1;
    }
    return res;
}

int main(){
    ll n,t=0;
    while(cin>>n&&n){
        ll k=gcd(9*n,8);
        //if(k==1){
        //    cout<<"Case "<<++t<<": 0\n";
        //    continue;
        //}
        ll p=9*n/k;
        if(gcd(p,10)!=1){
            cout<<"Case "<<++t<<": 0\n";
            continue;
        }
        ll e=phi(p);
        int ju=0;
        for(ll i=1;i<=e/i;i++){
            if(e%i==0&&qmi(10,i,p)==1){
                printf("Case %lld: %lld\n",++t,i);
                ju=1;
                break;
            }
        }
        if(ju)continue;
        for(ll i=sqrt(e);i>=1;i--){
            if(e%(e/i)==0&&qmi(10,e/i,p)==1){
                printf("Case %lld: %lld\n",++t,e/i);
                break;
            }
        }
    }
}


标签:Luckiest,10,frac,gcd,res,ll,number,同余,9L
来源: https://blog.csdn.net/m0_51841071/article/details/116664690