最幸運的數字
題目傳送門
根據題意
1 0 x − 1 9 ∗ 8 ≡ 0 ( m o d L ) \frac{10^x-1}{9}*8\equiv0\pmod{L} 910x−1∗8≡0(modL)
( 1 0 x − 1 ) ∗ 8 ≡ 0 ( m o d 9 L ) (10^x-1)*8\equiv0\pmod{9L} (10x−1)∗8≡0(mod9L)
令d=gcd(8,L)
(
1
0
x
−
1
)
∗
8
d
≡
0
(
m
o
d
9
L
d
)
(10^x-1)*\frac{8}{d}\equiv0\pmod{\frac{9L}{d}}
(10x−1)∗d8≡0(modd9
那麼此時 8 d 和 9 L d \frac{8}{d}和\frac{9L}{d} d8和d9L一定是互質的,所以** ( 1 0 x − 1 ) ≡ 0 ( m o d 9 L d ) (10^x-1)\equiv0\pmod{\frac{9L}{d}} (10x−1)≡0(modd9L)**
**所以 1 0 x ≡ 1 ( m o d 9 L d ) 10^x\equiv1\pmod{\frac{9L}{d}} 10x≡1(modd9L)
假設p= 9 L d \frac{9L}{d} d9L,當p和10互質時, Φ ( p ) \Phi(p) Φ(p)為其中一個解
我們可以證明最小的整數解一定是
Φ
(
p
)
\Phi(p)
如果不是約數的話,那麼a= Φ ( p ) \Phi(p) Φ(p)+r,就會推出 1 0 r ≡ 1 ( m o d 9 L d ) 10^r\equiv1\pmod{\frac{9L}{d}} 10r≡1(modd9L)
與a是最小解矛盾
所以問題轉換為求 Φ ( p ) \Phi(p) Φ(p)的約數,再對約數進行檢查是否滿足 1 0 x ≡ 1 ( m o d 9 L d ) 10^x\equiv1\pmod{\frac{9L}{d}} 10x≡1(modd9L)
時間複雜度
1.求
9
L
d
\frac{9L}{d}
d9L,複雜度為
O
(
L
)
O(\sqrt[]{L})
2.求
Φ
(
p
)
\Phi(p)
Φ(p)的以及約數為
O
(
Φ
(
p
)
+
p
)
O(\sqrt[]{\Phi(p)}+\sqrt[]{p})
O(Φ(p)
+p
)
3.用龜速冪檢查O(
l
o
g
Φ
(
p
)
∗
l
o
g
Φ
(
p
)
log\Phi(p)*log\Phi(p)
logΦ(p)∗logΦ(p))
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int cnt;
ll qmul(ll a,ll b,ll mod) //龜速冪,因為mod可能超過1e9,導致a*a超過longlong的範圍
{
ll res=0;
while(b)
{
if(b&1) res=(res+a)%mod;
a=(a+a)%mod;
b>>=1;
}
return res;
}
ll qmi(ll a,ll b,ll mod)
{
ll res=1;
while(b)
{
if(b&1) res=qmul(res,a,mod);
a=qmul(a,a,mod);
b>>=1;
}
return res;
}
int phi(ll x)
{
ll res=x;
for(ll i=2;i<=x/i;i++)
{
if(x%i==0)
{
res=res/i*(i-1);
while(x%i==0) x/=i;
}
}
if(x>1) res=res/x*(x-1);
return res;
}
ll gcd(ll a,ll b)
{
return b==0?a:gcd(b,a%b);
}
int main()
{
ll l;
while(scanf("%lld ",&l)&&l)
{
cnt++;
bool flag=false;
ll mod=9*l/gcd(8*1ll,l);
ll p=phi(mod);
ll res=1e18;
for(ll i=1;i<=p/i;i++)
{
if(p%i==0)
{
if(qmi(10,i,mod)==1) res=min(res,i);
if(i!=p/i&&qmi(10,p/i,mod)==1) res=min(res,p/i);
}
}
printf("Case %d: %lld\n",cnt,res==1e18?0:res);
}
return 0;
}