标签:快速幂 soft std 题意 ace namespace names 自己 poj
昨天终于把欧拉定理的证明看明白了。。。于是兴冲冲地写了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
POJ3696 The Luckiest Number 欧拉定理
标签:快速幂 soft std 题意 ace namespace names 自己 poj
原文地址:https://www.cnblogs.com/Jackpei/p/10848288.html