文章目录
一、欧拉定理
1.内容
正整数a和n互质,则 a φ ( n ) a^{φ(n)} aφ(n) ≡1 (mod n)
2.证明
φ(n)是指小于等于n的且与n互质的正整数的个数,将这些满足条件的正整数归为一个集合,也就是模n的简化剩余系,称为完全余数集合,以集合 Z n = Z_n= Zn={ x 1 , x 2 , . . . , x φ ( n ) x_1,x_2,...,x_{φ(n)} x1,x2,...,xφ(n)}来表示。
此时我们再构造一个集合 S = S= S={ ( a x 1 ) (ax_1) (ax1)%n, ( a x 2 ) (ax_2) (ax2)%n,…, ( a x φ ( n ) ) (ax_{φ(n)}) (axφ(n))%n}(a与n为互质关系)
此时我们第一个任务是证明
Z
n
Z_n
Zn与
S
S
S的等价性,即内部元素为一一对应的关系;
第二个任务是证明
a
φ
(
n
)
x
1
x
2
.
.
.
x
φ
(
n
)
≡
x
1
x
2
.
.
.
x
φ
(
n
)
(
m
o
d
n
)
a ^{φ(n)} x_1x_2 ...x _{φ(n)} ≡ x_1 x _2 ... x_{ φ(n)} (mod n)
aφ(n)x1x2...xφ(n)≡x1x2...xφ(n)(modn),从而证明欧拉定理。
1.证明 Z n Z_n Zn与 S S S的等价性
既然要证明
Z
n
Z_n
Zn与
S
S
S等价,就是要证明S中的元素满足两个条件:
1.
(
a
x
i
)
(ax_i)
(axi)%n一定在
Z
n
Z_n
Zn中存在;
2.
(
a
x
i
)
(ax_i)
(axi)%n与
(
a
x
j
)
(ax_j)
(axj)%n不会相等;
从而可以保证一一对应关系的成立。
1. ( a x i ) (ax_i) (axi)%n一定在 Z n Z_n Zn中存在
已知a与n互质, x i x_i xi与n互质,所以 a x i ax_i axi与n仍然不会有公因子,同样满足互质关系,此时就是要证明 ( a x i ) (ax_i) (axi)%n是否与n互质。
问题简化一下就是问,当a与b互质时,a%b的结果是否也与b互质。
令c=a%b,那么有式子
a
=
k
∗
b
+
c
(
k
≥
0
,
0
≤
c
<
b
)
a=k*b+c(k\geq0,0\leq c <b)
a=k∗b+c(k≥0,0≤c<b)
此时要证明c是否与b互质。
不妨先假设b与c不互质,两者存在一个质因子d,那么
b=md,c=nd
由于
a
=
k
∗
b
+
c
(
k
≥
0
,
0
≤
c
<
b
)
a=k*b+c(k\geq0,0\leq c <b)
a=k∗b+c(k≥0,0≤c<b),式子可以写为
a
=
k
m
∗
b
+
n
d
=
(
k
m
+
n
)
d
a=km*b+nd=(km+n)d
a=km∗b+nd=(km+n)d
也就说明a与b不满足互质关系,与条件不符。
所以反证可知当a与b互质时,a%b的结果与b仍然互质。
也就说明了
(
a
x
i
)
(ax_i)
(axi)%n与n互质,
(
a
x
i
)
(ax_i)
(axi)%n必然与
Z
n
Z_n
Zn中的一个元素对应。
2.证明 ( a x i ) (ax_i) (axi)%n与 ( a x j ) (ax_j) (axj)%n不会相等
仍然反证,假设存在相等的情况,
那么有:
a
x
i
≡
a
x
j
(
m
o
d
n
)
ax_i ≡ax_j(mod n)
axi≡axj(modn)
根据消去律:
x
i
≡
x
j
(
m
o
d
n
g
c
d
(
a
,
n
)
)
x_i ≡x_j(mod \frac{n}{gcd(a,n)})
xi≡xj(modgcd(a,n)n)
因为a与n互质,式子就说明
x
i
x_i
xi
x
j
x_j
xj需要在满足小于n的条件下满足同余关系,那么只能
x
i
=
x
j
x_i=x_j
xi=xj
所以当 x i ≠ x j x_i\neq x_j xi=xj时, ( a x i ) (ax_i) (axi)%n与 ( a x j ) (ax_j) (axj)%n不会相等。
2.证明 a φ ( n ) x 1 x 2 . . . x φ ( n ) ≡ x 1 x 2 . . . x φ ( n ) ( m o d n ) a ^{φ(n)} x_1x_2 ...x _{φ(n)} ≡ x_1 x _2 ... x_{ φ(n)} (mod n) aφ(n)x1x2...xφ(n)≡x1x2...xφ(n)(modn)
此时左式可以转化为(
(
a
x
1
)
(ax_1)
(ax1)%n *
(
a
x
2
)
(ax_2)
(ax2)%n…
(
a
x
φ
(
n
)
)
(ax_{φ(n)})
(axφ(n))%n) % n,刚刚已经证明了元素之间一一对应的关系,所以左式可以写为
(
x
1
x
2
.
.
.
x
φ
(
n
)
)
m
o
d
n
(x_1 x _2 ... x_{ φ(n)} )mod n
(x1x2...xφ(n))modn,证明两式相等。
两式相等,再次利用消去律,已知互质关系,可以直接消去,
得:
a
φ
(
n
)
a^{φ(n)}
aφ(n) ≡1 (mod n)
证毕
二、费马小定理
1.内容
若正整数 a 与 素数p 互质,则有
a
p
−
1
≡
1
(
m
o
d
p
)
a^{p-1} ≡ 1 (mod p)
ap−1≡1(modp) ,
或写为
a
p
≡
a
(
m
o
d
p
)
a^p ≡ a (mod p)
ap≡a(modp)
2.证明
简单证明就是直接利用欧拉定理来证明。
三、例题——The Luckiest number
1.大意
给定一个数字n,找出只由数字8所组成的n的最小倍数。
2.分析
即求x,使得
(
1
0
x
−
1
)
∗
8
9
≡
0
(
m
o
d
n
)
(10^x-1)*\frac{8}{9} ≡ 0(mod n)
(10x−1)∗98≡0(modn)
通过同余式计算的性质,可以把式子转化为:
1
0
x
≡
1
(
m
o
d
9
n
g
c
d
(
8
,
n
)
)
10^x≡ 1(mod \frac{9n}{gcd(8,n)})
10x≡1(modgcd(8,n)9n)
令 m = 9 n g c d ( 8 , n ) m=\frac{9n}{gcd(8,n)} m=gcd(8,n)9n
当gcd(10,m)>1时,无解:
反证,若10与m存在质因子d,则
10
=
u
d
,
m
=
v
d
10=ud,m=vd
10=ud,m=vd
式子变为:
u
x
d
x
=
k
v
d
+
1
(
k
≥
0
)
u^xd^x=kvd+1(k \geq0 )
uxdx=kvd+1(k≥0)
(
v
x
d
x
−
1
−
k
v
)
d
=
1
(v^xd^{x-1}-kv)d=1
(vxdx−1−kv)d=1
由于
d
≥
2
,
(
v
x
d
x
−
1
−
k
v
)
d \geq2,(v^xd^{x-1}-kv)
d≥2,(vxdx−1−kv)是整数,所以式子不成立,故只在gcd(10,m)=1时有解。
当gcd(10,m)=1时,其实就满足了欧拉定理的条件,存在式子:
1
0
φ
(
m
)
≡
1
(
m
o
d
m
)
10^{φ(m)} ≡1 (mod m)
10φ(m)≡1(modm)
可以说明存在一个解为φ(m),但这个解不能说明就是最小的解。
如果存在一个比φ(m)更小的解r,仍然满足式子
1
0
r
≡
1
(
m
o
d
m
)
10^{r} ≡1 (mod m)
10r≡1(modm)
那么就满足式子
1
0
r
=
k
m
+
1
10^r=km+1
10r=km+1
j结合上式
1
0
φ
(
m
)
=
t
m
+
1
10^{φ(m)}=tm+1
10φ(m)=tm+1
得到
1
0
φ
(
m
)
−
1
0
r
=
(
t
−
k
)
m
10^{φ(m)}-10^r=(t-k)m
10φ(m)−10r=(t−k)m
1
0
r
(
1
0
φ
(
m
)
r
−
1
)
=
(
t
−
k
)
m
10^r(10^{\frac{φ(m)}{r}}-1)=(t-k)m
10r(10rφ(m)−1)=(t−k)m
已知右边为整数,左边的
1
0
r
10^r
10r也为整数,故
(
1
0
φ
(
m
)
r
−
1
)
(10^{\frac{φ(m)}{r}}-1)
(10rφ(m)−1)也一定为整数,所以r一定是φ(m)的约数.
所以最后是不断枚举φ(m)的约数,并使用快速幂来验证。
3.代码
注意使用快速乘
#include<iostream>
using namespace std;
typedef long long ll;
ll gcd(ll a,ll b){
return b?gcd(b,a%b):a;
}
ll euler(ll n){
ll res=n,a=n;
for(ll i=2;i*i<=a;i++){
if(a%i==0){
res=res/i*(i-1);
while(a%i==0) a/=i;
}
}
if(a>1) res=res/a*(a-1);
return res;
}
ll quick_multiply(ll a,ll b,ll mod){
ll ans=0;
a%=mod;
b%=mod;
while(b){
if(b&1) ans=(ans+a)%mod;
b>>=1;
a=(a+a)%mod;
}
return ans;
}
ll Pow(ll a,ll b,ll mod){
ll ans=1;
a%=mod;
while(b){
if(b&1) ans=quick_multiply(ans,a,mod);
b>>=1;
a=quick_multiply(a,a,mod);
}
return ans;
}
int main(){
ll t=1,n;
while(cin>>n&&n){
ll tmp=gcd(9*n,8);
tmp=9*n/tmp;
if(gcd(tmp,10)!=1)cout<<"Case "<<(t++)<<": "<<0<<endl;
else{
ll res=euler(tmp);
ll mi=res;
for(ll i=1;i*i<=res;i++){
if(res%i==0){
if(Pow(10,i,tmp)==1){
mi=min(mi,i);
}
if(Pow(10,res/i,tmp)==1){
mi=min(mi,res/i);
}
}
}
cout<<"Case "<<(t++)<<": "<<mi<<endl;
}
}
}