1、求快速幂
首先补充下模运算的基本运算规则
(a + b) % p = (a % p + b % p) % p (1)
(a - b) % p = (a % p - b % p ) % p (2)
(a * b) % p = (a % p * b % p) % p (3)
(a^b) % p = ((a % p)^b) % p (4)
快速幂,是为了快速求出形如
a
k
m
o
d
p
a^k mod \ p
akmod p的值的问题。其解决思路如下:
将k拆解为如下的形式
k
=
2
0
+
2
1
+
2
2
+
.
.
.
2
p
k = 2^0 + 2^1 + 2^2 + ... 2^p
k=20+21+22+...2p
a
k
=
a
2
0
+
2
1
+
2
2
+
.
.
.
2
p
=
a
2
0
∗
a
2
1
∗
.
.
.
∗
a
2
p
m
o
d
p
a ^k = a^{ 2^0 + 2^1 + 2^2 + ... 2^p}=a^{2^0}*a^{2^1}*...*a^{2^p} mod\ p
ak=a20+21+22+...2p=a20∗a21∗...∗a2pmod p由(3)式可得
上
式
=
a
2
0
m
o
d
p
∗
a
2
1
m
o
d
p
∗
.
.
.
∗
a
2
p
m
o
d
p
上式=a^{2^0}mod\ p*a^{2^1} mod \ p*...*a^{2^p} mod\ p
上式=a20mod p∗a21mod p∗...∗a2pmod p
所以我们可以得到如下代码所示的做法
//a 为底数,k为指数,p为要mod的数
int qmi(int a, int k, int p)
{
int res = 1;
while(k)
{
if(k & 1) res = res * a % p;
k >>= 1;
a = a * a % p;
}
return res;
}
时间复杂度:O(logk)
2、快速幂求乘法逆元
先上两个定理
- 若a与n互质,则 a ϕ ( n ) ≡ 1 m o d n a^{\phi(n)}\equiv 1\ mod\ n aϕ(n)≡1 mod n
- 特别的,当n为质数p的时候, a p − 1 ≡ 1 m o d p a^{p-1} \equiv 1\ mod\ p ap−1≡1 mod p
b 存在乘法逆元的充要条件是 b 与模数 m 互质。当模数 m 为质数时,
b
m
−
2
b^{m−2}
bm−2 即为 b 的乘法逆元
所谓乘法逆元,假设b的乘法逆元为x,则有
a
b
≡
a
∗
x
(
m
o
d
m
)
\frac{a}{b} \equiv a *x(mod \ m)
ba≡a∗x(mod m)
b
∗
x
≡
1
(
m
o
d
m
)
b * x \equiv 1(mod \ m)
b∗x≡1(mod m)
如果m为质数,则可以利用上面的定理得到一个数的逆元,也即有
b
m
−
1
≡
1
(
m
o
d
m
)
b^{m -1} \equiv 1(mod\ m)
bm−1≡1(mod m)
b
∗
b
m
−
2
≡
1
(
m
o
d
m
)
\ b* b^{m -2} \equiv 1(mod\ m)
b∗bm−2≡1(mod m)
。
所以此时b的乘法逆元即为
b
m
−
2
b^{m-2}
bm−2,可用快速幂求得