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;
                }
            }
        }
    }
  • 相关阅读:
    一个简单的knockout.js 和easyui的绑定
    knockoutjs + easyui.treegrid 可编辑的自定义绑定插件
    Knockout自定义绑定my97datepicker
    去除小数后多余的0
    Windows Azure Web Site (15) 取消Azure Web Site默认的IIS ARR
    Azure ARM (1) UI初探
    Azure Redis Cache (3) 创建和使用P级别的Redis Cache
    Windows Azure HandBook (7) 基于Azure Web App的企业官网改造
    Windows Azure Storage (23) 计算Azure VHD实际使用容量
    Windows Azure Virtual Network (11) 创建VNet-to-VNet的连接
  • 原文地址:https://www.cnblogs.com/superminivan/p/10863420.html
Copyright © 2011-2022 走看看