题意:
Bob最喜欢的数字是8,他的幸运数字是能整除L的全8序列的最短长度。
请找到Bob的幸运数字,若无则输出0
例如:L=1,ans=1;L=2,ans=1;L=8,ans=1;L=11,ans=2.
分析:
注意到凡是那种1111111..... 2222222..... 33333.....
之类的序列都可用这个式子来表示:k*(10^n-1)/9
进而简化:8 * (10^n-1)/9=L * k (k是一个整数)
-->8 * (10^n-1)=9L *
-->d=gcd(8,L) 8*(10^n-1)/d=9k * L/d
-->令p=8/d q=9kL/d p*(10^n-1)=q
--->因为p,q互质, 10^n=1 mod q
由欧拉定理可知,当q与10互质的时候,10^(phi(q))=1 mod q
所以无解的时候就是q与10不互质的时候,此外我们求phi(q)的所有因子,按小到大排序,第一个满足10^x =1 mod q的输出。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#define LL long long
using namespace std;
const LL MAX=100000000000;
LL phi(LL n){
LL x=n,i;
LL ans=n;
for(i=2;i*i<=x;i++){
if(x%i==0){
ans=ans/i*(i-1);
while(x%i==0)
x/=i;
}
}
if(x!=1)
ans=ans/x*(x-1);
return ans;
}
LL multi(LL a,LL b,LL m){//a*b%m
LL ret=0;
while(b>0){
if(b&1){
ret+=a;
if(ret>=m)
ret-=m;
}
a+=a;
if(a>=m)
a-=m;
b>>=1;
}
return ret;
}
LL quickmod(LL a,LL n,LL MOD){//a^n%MOD
LL ans=1;
ans%=MOD;
for(;n>0;n>>=1,a=multi(a,a,MOD))
if(n&1)
ans=multi(ans,a,MOD);
return ans;
}
int main(){
int cas=0;
LL n,i;
while(~scanf("%lld",&n)&&n){
int k=0;
while(n%2==0){
n/=2;
k++;
}
if(k>3||n%5==0){
printf("Case %d: 0\n",++cas);
continue;
}
n*=9;
LL len=phi(n);
LL ans=MAX;
for(i=1;i*i<=len;i++){
if(len%i==0){
LL f=len/i;
if(quickmod(10,i,n)==1) ans=min(ans,i);
if(quickmod(10,f,n)==1) ans=min(ans,f);
}
}
if(ans==MAX) ans=0;
printf("Case %d: %lld\n",++cas,ans);
}
return 0;
}
来源:CSDN
作者:bookybooky
链接:https://blog.csdn.net/Booky_Amnesia/article/details/42588709