定理
假设p为质数,a不是p的倍数,则有
a
p
−
1
≡
1
(
m
o
d
p
)
a^{p-1}\equiv 1(mod \space p)
ap−1≡1(mod p)
例子
求
2
100
关
于
13
的
余
数
2^{100}关于13的余数
2100关于13的余数
2
100
=
2
12
×
8
⋅
2
4
=
16
(
m
o
d
13
)
=
3
(
m
o
d
13
)
2^{100}=2^{12 \times 8} \cdot2^4=16 (mod \space 13)=3 (mod \space 13)
2100=212×8⋅24=16(mod 13)=3(mod 13)
代码
假 设 我 们 要 求 2 k m o d p , k ∈ [ 1 , 100 ] 假设我们要求2^k \space mod \space p, k \in [1, 100] 假设我们要求2k mod p,k∈[1,100]
#include<iostream>
#include<cmath>
using namespace std;
int fun1(int a, int p, int mod){
int ans = pow(a, p % (mod-1));
ans %= mod;
return ans;
}
int fun2(int a, int p, int mod){
int ans = pow(a, p);
ans %= mod;
return ans;
}
int fun3(int a, int p, int mod){
int ans = 1;
while(p--){
ans *= a;
ans %= mod;
}
ans %= mod;
return ans;
}
int main(){
for(int i=1; i <= 100; i++){
cout<<fun1(2, i, 13)<<" "<<fun1(2, i, 13)<<" "<<fun1(2, i, 13)<<endl;
}
return 0;
}
fun2和fun3都会受到时间或者空间的限制,而fun1直接使用了费马小定理可以迅速的求取答案
逆元
如
果
a
×
b
=
1
(
m
o
d
p
)
,
则
a
为
b
互
为
m
o
d
p
逆
元
如果a \times b = 1 (mod \space p),则a为b互为mod \space p逆元
如果a×b=1(mod p),则a为b互为mod p逆元
根据费马小定理得
a
p
−
1
≡
1
(
m
o
d
p
)
⟹
a
×
a
p
−
2
≡
1
(
m
o
d
p
)
所
以
a
和
a
p
−
2
互
为
m
o
d
p
逆
元
a^{p-1} \equiv 1 (mod \space p) \\\implies a \times a^{p-2} \equiv 1 (mod \space p) \\ 所以a和a^{p-2}互为mod \space p逆元
ap−1≡1(mod p)⟹a×ap−2≡1(mod p)所以a和ap−2互为mod p逆元
费马小定理一般和快速幂配合使用,下面我们介绍一下快速幂
快速幂代码
#include<iostream>
#include<cmath>
using namespace std;
int normal_pow(int a, int p){
int ans = pow(a, p);
return ans;
}
int qpow_1(int a, int p){
if(p==0){
return 1;
}else if(p % 2 == 1){
return qpow_1(a, p-1) * a;
}else{
int temp = qpow_1(a, p / 2);
return temp * temp;
}
}
int qpow_2(int a, int p){
int ans = 1;
while(p){
if(p & 1){
ans *= a;
}
a *= a;
p >>= 1;
}
return ans;
}
int main(){
for(int i=1; i <= 10; i++){
cout<<normal_pow(2, i)<<" "<<qpow_1(2, i)<<" "<<qpow_2(2, i)<<endl;
}
return 0;
}
快速幂求逆元
normal_pow是普通的求幂,qpow_1是递归方式实现快速幂,qpow_2用循环的方式实现快速幂,求逆元即求qpow_1(a, p-2)
或qpow_2(a, p-2)