即求出一个 (x) 使得 (L|8 imes (10^x-1)/9),记 (d=(L,8))。
[L|8 imes (10^x-1)/9 Leftrightarrow frac{9L}{d}|(10^x-1) Leftrightarrow 10^x equiv 1 pmod {frac{9L}{d}}
]
有引理: 若 ((a,n)=1),则满足 (a^x equiv 1 pmod n) 的最小 (x) 必为 (varphi(n)) 的约数。
证明: 假设不可,则 (varphi(n)=qx+r),(a^x equiv 1 pmod n Leftrightarrow a^{qx} equiv 1 pmod n),又 (a^{varphi(n)} equiv 1 pmod n),则 (a^r equiv 1 pmod n)。(r<x),矛盾,证毕。
因此枚举 (varphi(9L/d)) 的约数一一验证即可。
#include <iostream>
#include <cstdio>
using namespace std;
typedef long long ll;
ll l, ans;
int n;
ll gcd(ll a, ll b){
return !b?a:gcd(b, a%b);
}
ll getPhi(ll x){
ll re=x;
for(ll i=2; i*i<=x; i++)
if(x%i==0){
re = re / i * (i - 1);
while(x%i==0) x /= i;
}
if(x>1) re = re / x * (x - 1);
return re;
}
ll mul(ll a, ll b, ll p){
ll re=0;
while(b){
if(b&1) re = (re + a) % p;
a = (a + a) % p;
b >>= 1;
}
return re;
}
ll ksm(ll a, ll b, ll p){
ll re=1;
while(b){
if(b&1) re = mul(re, a, p);
a = mul(a, a, p);
b >>= 1;
}
return re;
}
int main(){
while(scanf("%lld", &l)!=EOF){
if(!l) break;
ans = 0x3f3f3f3f3f3f3f3f;
ll d=gcd(l, 8);
ll phi=getPhi(9*l/d);
for(ll i=1; i*i<=phi; i++)
if(phi%i==0){
if(ksm(10, i, 9*l/d)==1)
ans = min(ans, i);
if(ksm(10, phi/i, 9*l/d)==1)
ans = min(ans, phi/i);
}
printf("Case %d: %lld
", ++n, ans==0x3f3f3f3f3f3f3f3f?0:ans);
}
return 0;
}