S
S
S表示
p
p
p的二进制权位序列:
2
n
,
.
.
.
,
2
3
,
2
2
,
2
1
,
2
0
2^n,...,2^3,2^2,2^1,2^0
2n,...,23,22,21,20。
B
B
B表示
p
p
p的二进制序列。
b
p
b^p
bp可以表示成
b
p
=
∏
k
=
0
n
b
S
k
∗
B
k
b^p =\prod_{k=0}^{n} b^{S_k*B_k}
bp=k=0∏nbSk∗Bk
记
T
k
=
b
S
k
∗
B
k
T_k=b^{S_k*B_k}
Tk=bSk∗Bk,
T
k
=
{
1
B
k
=
0
b
2
k
B
k
=
1
T_k= \begin{cases} 1 &B_k=0 \\ b^{2^k}& B_k=1 \end{cases}
Tk={1b2kBk=0Bk=1
可以观察发现,
(1)
B
k
B_k
Bk决定了第
k
k
k项
T
k
T_k
Tk 是否应该放入累乘中。
(2)存在递推关系
T
k
+
1
=
T
k
∗
T
k
T_{k+1}=T_k*T_k
Tk+1=Tk∗Tk。
以
3
13
3^{13}
313为例。13的二进制序列为1101,从右开始数,0号位为1,1号位为0,2号位为1,3号位为1。则
B
=
1
,
1
,
0
,
1
B=1,1,0,1
B=1,1,0,1
S
=
2
3
,
2
2
,
2
1
,
2
0
S=2^3,2^2,2^1,2^0
S=23,22,21,20
T
=
3
8
,
3
4
,
3
2
,
3
1
T=3^8,3^4,3^2,3^1
T=38,34,32,31,故
3
13
=
3
∗
1
∗
3
4
∗
3
8
3^{13}=3*1*3^4*3^8
313=3∗1∗34∗38。
1,快速幂的迭代法:
long long binaryPow(long long b, long long p)
{
long long r = 1;
while(p>0)
{
if(p & 1) // 判断p的二进制末位是不是1
{
r = r * b;
}
p = p >> 1; // p的二进制右移一位
b = b * b;
}
return r;
}
2,快速幂取余:
涉及到同余的性质
a
b
m
o
d
n
=
[
(
a
m
o
d
n
)
(
b
m
o
d
n
)
]
m
o
d
n
ab\ mod\ n=[(a\ mod\ n)(b\ mod\ n)]\ mod\ n
ab mod n=[(a mod n)(b mod n)] mod n即乘积的模等于乘数模的乘积的模。
long long binaryPowMod(long long b, long long p, long long m)
{
long long r = 1;
while(p>0)
{
if(p & 1) // 判断p的二进制末位是不是1
{
r = r * b % m;
}
p = p >> 1; // p的二进制右移一位
b = b * b % m;
}
return r;
}
推荐一篇通俗易懂的博客可以参考:快速幂算法从零开始一步一步优化