正题
题目链接:http://poj.org/problem?id=3696
题目大意
求多少个8连在一起是LL的倍数。
解题思路
将x个8连在一起分解一下
那么就是
L|2∗(10x−1)9L|2∗(10x−1)9
d=gcd(L,8)d=gcd(L,8)
分解一下
9Ld|10x−19Ld|10x−1
然后
10x≡1(mod 9Ld)10x≡1(mod9Ld)
根据欧拉定理,若 gcd(a,n)=1gcd(a,n)=1
ax≡1(mod n)ax≡1(modn)时 xx是的约数。
所以我们就可以枚举 φ(n)φ(n)的约数计算前面的答案。
code
#include<cstdio>
#include<algorithm>
#define ll long long
using namespace std;
ll L,tot;
ll gcd(ll a,ll b)
{return a==0?b:gcd(b%a,a);}
ll mul(ll x,ll k)//慢速乘免爆炸
{ll ans=0;while(k){if (k&1) ans=(ans+x)%L;x=(x*2)%L;k>>=1;}return ans;
}
ll phi(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 power(ll x,ll b)//快速幂
{ll sum=1;while(b){if(b&1) sum=mul(sum,x);x=mul(x,x);b>>=1;}return sum;
}
int main()
{while(scanf("%lld",&L)&&L){L=9*L/gcd(L,8LL);if(gcd(L,10LL)!=1)//永远不可能{printf("Case %lld: 0\n",++tot);continue;}ll ans=(1LL<<63-1),a=phi(L);//计算欧拉函数for(ll i=1;i*i<=a;i++)if(a%i==0){if(power(10,i)==1)//判断答案ans=min(ans,i);if(power(10,a/i)==1)//判断答案ans=min(ans,a/i);}printf("Case %lld: %lld\n",++tot,ans);}
}