zoukankan      html  css  js  c++  java
  • [题解](同余)POJ_3696_The Luckiest Number

    还是挺难的吧......勉强看懂调了半天

    首先表达式可以写成 8(10^x -1)/9,题意为求一个最小的x使L | 8(10^x -1)/9

    设d=gcd(L,8)

    L | 8(10^x -1)/9

    <=>9L | 8(10^x -1)

    <=>9L/d | 10^x -1 (因为 9L/d 和 8/d 互质了 所以 9L/d 能整除(8/d)*(10^x-1)和 8/d 无关,所以可以去掉)

    <=>10^x 同余 1(mod 9L/d)

    引理:

    若a,n互质,则满足10^x同余1(mod n)的最小正整数x0是phi(n)的约数

    反证法:

    假设满足a^x 同余 1(mod n)的最小正整数x0不能整除phi(n)

    设phi(n)=q*x0+r(0<r<x0),因为a^x0 同余1(mod n),所以a^(q*x0)同余1(mod n)

    根据欧拉定理a^phi(n)同余1(mod n),所以a^r同余1(mod n),与x0最小矛盾

    无解的时候就是q与10不互质的时候,因为若q与10有公因子d:
    1.若d=2,q=2*k,那么10^x=2^x*5^x=1%2k
       即2^x*5^x=1+2k*m,左边为偶数,右边为奇数,显然矛盾。
    2.若d=5,q=5*k,那么10^x=2^x*5^x=1%5k
       即2^x*5^x=1+5k*m,左边是5的倍数,右边不是5的倍数,显然矛盾。

    注意:乘的时候会爆longlong,手写乘法,要用根号的试除法求约数,不然会T

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #define ll long long
    using namespace std;
    ll n,cnt;
    ll x[100000];
    ll gcd(ll a,ll b){
        return b?gcd(b,a%b):a;
    }
    ll eular(ll n){
        ll ans=n;
        for(ll i=2;i*i<=n;i++){
            if(n%i==0){
                ans=ans/i*(i-1);
                while(n%i==0)n/=i;
            }
        }
        if(n>1)ans=ans/n*(n-1);
        return ans;
    }
    ll mul(ll a,ll b,ll mod){
        ll ans=0;
        while(b){
            if(b&1)ans=(ans+a)%mod;
            a=(a<<1)%mod;
            b>>=1;
        }
        return ans;
    }
    ll qpow(ll a,ll b,ll mod){
        ll base=a,ans=1;
        while(b){
            if(b&1)ans=mul(ans,base,mod);
            base=mul(base,base,mod);
            b>>=1;
        }
        return ans%mod;
    }
    
    int main(){
        int t=0;
        while(1){
            int fl=0;cnt=0;
            scanf("%lld",&n);
            if(n==0)break;
            ll d=9*n/gcd(n,8);
            if(gcd(10,d)!=1){
                printf("Case %d: 0
    ",++t);
            }
            else{
                ll phi=eular(d);
                for(ll i=1;i*i<=phi;i++){
                    if(phi%i==0){
                        x[++cnt]=i;
                        if(i*i!=phi)x[++cnt]=phi/i;
                    }
                }
                
                sort(x+1,x+cnt+1);
                for(int i=1;i<=cnt;i++)
                if(qpow(10,x[i],d)==1){
                    printf("Case %d: %lld
    ",++t,x[i]);
                    break;
                }
            }
        }
    }
  • 相关阅读:
    系统测试的策略
    POJ1611(并查集)
    POJ2752(KMP)
    POJ3176(DP)
    HDU2579(BFS)
    HDOJ1175(BFS)
    HDOJ1242(BFS)
    HDOJ1180(BFS)
    HDOJ1372(BFS)
    HDOJ2717(BFS)
  • 原文地址:https://www.cnblogs.com/superminivan/p/10863420.html
Copyright © 2011-2022 走看看