POJ3696 The Luckiest Number 欧拉定理

昨天终于把欧拉定理的证明看明白了。。。于是兴冲冲地写了2道题,发现自己啥都不会qwq


 

题意:给定一个正整数L<=2E+9,求至少多少个8连在一起组成正整数是L的倍数。

这很有意思么。。。

首先,连续的8可表示为:8*(10^x-1)/9;

那么就是L|8*(10^x-1)/9 => 9*L|8*(10^x-1) ,求最小的x;

我们设d=gcd(L,8)

则9*L/d | 8/d*(10^x-1),因为此时9*L/d 和 8/d 互质,所以9*L/d | 10^x-1,所以 10^x ≡ 1 (mod 9*L/d);

然后要证明一个结论:a^x ≡ 1 (mod n)的最小正整数解x0能整除φ(n)

证明:

反证:设不能整除,则设φ(n)=q*x0+r;(1<=r<x0)

因为a^x0 ≡ 1 (mod n),所以a^(q*x0) ≡ 1(mod n)

又因为a^φ(n) ≡ 1 (mod n),所以a^r ≡ 1 (mod n)

因为r<x0,所以假设不成立;

证毕。

所以我们枚举每个φ(9*L/d) 的约数,用快速幂判断就好了。

#include<cstdio>
#include<iostream>
#include<algorithm>
#define ll long long
#define R register ll
using namespace std;
inline ll g() {
    R ret=0,fix=1; register char ch; while(!isdigit(ch=getchar())) fix=ch=='-'?-1:fix;
    do ret=ret*10+(ch^48); while(isdigit(ch=getchar())); return ret*fix;
}
ll a[500010],n,ans;
inline ll gcd(ll a,ll b) {return b?gcd(b,a%b):a;}
inline ll phi(ll n) {
    R m=n; for(R i=2;i*i<=n;++i) if(n%i==0) {
        m=m/i*(i-1);
        while(n%i==0) n/=i;
    } if(n>1) m=m/n*(n-1); return m;
}
inline ll mul(ll a,ll b) {
    a%=n,b%=n; R c=(long double)a*b/n;
    R ans=a*b-c*n; if(ans<0) ans+=n;
    if(ans>=n) ans-=n; return ans;
}
inline ll qpow(ll a,ll p) { R ret=1; 
    for(;p;p>>=1,a=mul(a,a)) if(p&1) ret=mul(ret,a); return ret;
}
signed main() { R t=0;
    while(n=g(),n!=0) { //cout<<n<<endl;
        n=9*n/gcd(8,n);
        printf("Case %d: ",++t);
        if(gcd(10,n)==1) {
            R p=phi(n),cnt=0; //cout<<"PHI: "<<p<<endl;
            for(R i=1;i*i<=p;++i) if(p%i==0) {
                a[++cnt]=i;
                if(i*i!=p) a[++cnt]=p/i;
            } sort(a+1,a+cnt+1); R i;
            for(i=1;i<=cnt;++i) if(qpow(10,a[i])==1) break;
            printf("%lld\n",a[i]);
        } else printf("0\n");
    }
}

2019.05.11

 

posted @ 2019-05-11 12:41  LuitaryiJack  阅读(149)  评论(0编辑  收藏  举报