题意:给定一个正整数 LLL2×109L\leq 2\times10^9

问至少多少个 88 连在一起组成的自然数是 LL 的倍数。

xx88 连在一起组成的正整数可写作 8(10x1)9\frac{8(10 ^x -1)}{9}。题目要求我们求最小 xx,使 L8(10x1)9L|\frac{8(10 ^x -1)}{9}。设 d=gcd(L,8)d=\gcd(L,8)

L8(10x1)99L8(10x1)9Ld10x110x1mod9Ld L| \frac{8(10 ^x -1)}{9} \longleftrightarrow 9L| 8(10^x -1) \longleftrightarrow \frac{9L}{d} |10 ^x-1 \longleftrightarrow 10 ^x \equiv 1\bmod \frac{9L}{d}

其中第二步到第三部的转换,因为 8d\frac{8}{d} 为整数,所以只会为 1,2,4,81,2,4,8,与 99 互质,而 Ld\frac{L}{d}8d\frac{8}{d} 互质,故右边可再除以一个 8d\frac{8}{d}

引理:

若正整数 a,na,n 互质,则满足 ax1modna ^x \equiv 1\bmod n 的最小正整数 x0x_0φ(n)\varphi(n) 的约数。

然后直接枚举其约数,一一检验即可。

code:

#include<cstdio>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<algorithm>
using namespace std;
long long gcd(long long a,long long b)
{
 	if(b==0)
		return a;
 	return gcd(b,a%b);
}
long long phi(long long x)
{
 	long long ans=x;
 	for(int 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;
}
long long power(long long a,long long b,long long p)
{
 	long long ans=1;
 	for(;b;b>>=1)
 	{
 		if(b&1)
 			ans=ans*a%p;
 		a=a*a%p;
 	}
 	return ans%p;
}
long long l,d,n,p,r,ans,cnt;
int main()
{
 	while(scanf("%lld",&l)!=EOF&&l)
 	{
 		cnt++;
 		ans=1e9;
 		d=0;
 		n=0;
 		p=0;
 		r=0;
 		d=gcd(l,(long long)8);
 		n=9*l/d;
 		r=phi(n);
 		for(long long i=1;i*i<=r;i++)
 		{
 			if(r%i==0)
 			{
 				if(power(10,i,n)==1)
 					ans=min(ans,i);
 				long long j=r/i;
 				if(i==j)
 					continue;
 				if(power(10,j,n)==1)
 					ans=min(ans,j);
 			}
 		}
 		if(ans==1e9)
 			ans=0;
 		printf("Case %lld: %lld\n",cnt,ans);
 	}
    return 0;
}