( ext{Solution})
首先可以把题意转化为求最小的 (x) 使得 (L|8 imes frac{10^x-1}{9})。
然后有 (9 imes L|8 imes (10^x-1))。
我们尝试去掉那个 (8),因为 (gcd(9,8)=gcd(8,10^x-1)=1),所以 (8) 贡献的因子一定只在 (L) 出现,(L) 中关于 (8) 的因子也只在 (8) 出现。就可以转化为 (frac{9 imes L}{gcd(8,L)}|10^x-1)。
显然就有 (10^xequiv 1 (operatorname{mod} frac{9 imes L}{gcd(8,L)})),我们令模数为 (p)。
首先,如果 (gcd(p,10) eq 1) 就一定无解,否则一定有解。令 (gcd(p,10)=g (g eq 1)),则 (p=a imes g,10=b imes g)。显然 (10^x) 一定会是 (g) 的倍数,用 (10^x) 减去若干个 (p)(模拟取模)一定是 (g) 的倍数,不会是 (1)。否则起码有欧拉定理撑着。
这里有个结论:
当 (gcd(a,p)=1),使得 (a^xequiv 1 ( ext{mod }p)) 成立的最小 (x) 是 (phi(p)) 的因数。
反证法。
设最小 (x) 满足 (phi(p)=k imes x+m (0<m<x))。(默认在取模 (p) 的情况下)
那么有 (a^{phi(p)}equiv a^{k imes x+m}equiv 1)。
又因为 (a^xequiv 1),显然 (a^{k imes x}equiv 1)。那么就有 (a^mequiv 1)。
但是 (m<x),所以 (x) 并不是最小的。所以结论得证。
注:模数较大,要多开 long long
,还要加上快速乘。
( ext{Code})
#include <cstdio>
#define rep(i,_l,_r) for(register signed i=(_l),_end=(_r);i<=_end;++i)
#define fep(i,_l,_r) for(register signed i=(_l),_end=(_r);i>=_end;--i)
#define erep(i,u) for(signed i=head[u],v=to[i];i;i=nxt[i],v=to[i])
#define efep(i,u) for(signed i=Head[u],v=to[i];i;i=nxt[i],v=to[i])
#define print(x,y) write(x),putchar(y)
template <class T> inline T read(const T sample) {
T x=0; int f=1; char s;
while((s=getchar())>'9'||s<'0') if(s=='-') f=-1;
while(s>='0'&&s<='9') x=(x<<1)+(x<<3)+(s^48),s=getchar();
return x*f;
}
template <class T> inline void write(const T x) {
if(x<0) return (void) (putchar('-'),write(-x));
if(x>9) write(x/10);
putchar(x%10^48);
}
template <class T> inline T Max(const T x,const T y) {if(x>y) return x; return y;}
template <class T> inline T Min(const T x,const T y) {if(x<y) return x; return y;}
template <class T> inline T fab(const T x) {return x>0?x:-x;}
template <class T> inline T Gcd(const T x,const T y) {return y?Gcd(y,x%y):x;}
template <class T> inline T Swap(T &x,T &y) {x^=y^=x^=y;}
typedef long long ll;
const ll inf=(1ll<<60);
ll p;
ll phi(ll x) {
ll r=x;
for(int i=2;i*i<=x;++i) {
if(x%i) continue;
r=r/i*(i-1);
while(x%i==0) x/=i;
}
if(x>1) r=r/x*(x-1);
return r;
}
ll gcd(ll x,ll y) {
if(!y) return x;
return gcd(y,x%y);
}
ll qkmul(ll x,ll y) {
ll r=0;
while(y) {
if(y&1) r=(r+x)%p;
x=(x+x)%p; y>>=1;
}
return r;
}
ll qkpow(ll x,ll y) {
ll r=1;
while(y) {
if(y&1) r=qkmul(r,x);
x=qkmul(x,x); y>>=1;
}
return r;
}
int main() {
int T=0,n; ll Phi,ans;
while(233) {
n=read(9);
if(!n) break;
p=1ll*n/gcd(n,8)*9;
if(gcd(10,p)>1) {printf("Case %d: 0
",++T); continue;}
Phi=phi(p); ans=inf;
for(ll i=1;i*i<=Phi;++i) {
if(Phi%i) continue;
if(qkpow(10,i)==1&&i<ans) ans=i;
if(qkpow(10,Phi/i)==1&&Phi/i<ans) ans=Phi/i;
}
printf("Case %d: %lld
",++T,ans);
}
return 0;
}