欢迎大家访问我的老师的OJ———caioj.cn
题面描述
思路
一句话题意:求至少多少个
8
8
8连在一次组成的正整数是
L
\operatorname{L}
L的倍数。
∵
x
个
8
\because x个8
∵x个8实际上就是
(
1
0
x
−
1
)
/
9
∗
8
(10^x-1)/9*8
(10x−1)/9∗8,现在我们可以转化一下题意:
求最小的
x
x
x,满足
L
∣
(
1
0
x
−
1
)
/
9
∗
8
\operatorname{L} \mid (10^x-1)/9*8
L∣(10x−1)/9∗8
L ∣ ( 1 0 x − 1 ) / 9 ∗ 8 ⟷ L ∗ 9 ∣ ( 1 0 x − 1 ) ∗ 8 ⟷ 9 L gcd ( 8 , L ) ∣ 1 0 x − 1 ⟷ 1 0 x ≡ 1 ( mod 9 L gcd ( 8 , L ) ) \operatorname{L} \mid (10^x-1)/9*8 \longleftrightarrow \operatorname{L}*9 \mid (10^x-1)*8\longleftrightarrow \frac{9\operatorname{L}}{\gcd(8,\operatorname{L})}\mid 10^x-1\longleftrightarrow 10^x \equiv 1(\operatorname{mod} \frac{9\operatorname{L}}{\gcd(8,\operatorname{L})}) L∣(10x−1)/9∗8⟷L∗9∣(10x−1)∗8⟷gcd(8,L)9L∣10x−1⟷10x≡1(modgcd(8,L)9L)
引理:
若正整数a,n互质,且满足 a x ≡ 1 ( mod n ) a^x\equiv 1(\operatorname{mod} n) ax≡1(modn)的最小正整数 x 0 x_0 x0是 φ ( n ) \varphi(n) φ(n)的约数。
证明:
假设满足 a x ≡ 1 ( mod n ) a^x\equiv 1(\operatorname{mod} n) ax≡1(modn)的最小正整数 x 0 x_0 x0不能整除 φ ( n ) \varphi(n) φ(n)。
设 φ ( n ) = q x 0 + r ( 0 < r < x 0 ) \varphi(n)=qx_0+r(0<r<x_0) φ(n)=qx0+r(0<r<x0).
因为 a x 0 ≡ 1 ( mod n ) a^{x_0}\equiv 1(\operatorname{mod} n) ax0≡1(modn),
则 a q x 0 ≡ 1 ( mod n ) a^{qx_0}\equiv 1(\operatorname{mod} n) aqx0≡1(modn),
又 a φ ( n ) ≡ 1 ( mod n ) a^{\varphi(n)}\equiv 1(\operatorname{mod} n) aφ(n)≡1(modn),
故 a r ≡ 1 ( mod n ) a^r\equiv 1(\operatorname{mod }n) ar≡1(modn),
与假设 x 0 x_0 x0最小相矛盾。故假设不成立。原命题成立。
证毕。
根据以上引理,我们只要求出 φ ( 9 L / g c d ( L , 8 ) ) \varphi(9L/gcd(L,8)) φ(9L/gcd(L,8)),枚举它的所有约数,用快速幂逐一检查是否满足条件即可。
AC code
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#define ll long long
#define gc getchar()
using namespace std;
const int N=15;
ll p[N];int c[N];int t=0;
inline void qr(ll &x)
{
x=0;int f=1;char c=gc;
while(c<'0'||c>'9'){if(c=='-')f=-1;c=gc;}
while(c>='0'&&c<='9'){x=x*10+(c^48);c=gc;}
x*=f;
}
ll L;
inline void mul(ll &a,ll b,ll p)
{
ll c=(long double)a*b/p;
a=a*b-c*p;
}
inline ll pow_mod(ll a,ll b,ll p)
{
ll ans=1%p;a%=p;
while(b)
{
if(b&1)mul(ans,a,p);
b>>=1;mul(a,a,p);
}
return ans;
}
inline ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
inline void div(ll x)
{
p[0]=0;
for(ll i=2;i*i<=x;i++)
if(x%i==0)
{
p[++p[0]]=i;
c[p[0]]=0;
while(x%i==0)x/=i,++c[p[0]];
}
if(x>1)p[++p[0]]=x,c[p[0]]=1;
}
bool dfs(int x,ll ans)
{
if(x>p[0])
{
if(pow_mod(10ll,ans,L)==1)return printf("Case %d: %lld\n",t,ans),true;
return false;
}
ll y=1;
for(int i=0;i<=c[x];i++)
{
if(dfs(x+1,ans*y))return true;
y*=p[x];
}
return false;
}
inline ll phi(ll x)
{
ll ans=x;
for(ll 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;
}
int main()
{
while(qr(L),L)
{
L=L*9/gcd(8,L);++t;
if(gcd(10ll,L)>1){printf("Case %d: 0\n",t);continue;}
ll phx=phi(L);
div(phx);
dfs(1,1);
}
return 0;
}