
快速幂
顾名思义,快速幂就是快速算底数的n次幂。其时间复杂度为 O(log₂N), 与朴素的O(N)相比效率有了极大的提高。
以a^b为例,假设b=11,则
$$
a^{11}=a^{2^{0}+2^{1}+2^{3}}
$$
因为11的二进制为1011,11=2^0 +2^1+2^3,所以可得上式。
所以我们只要判断幂的二进制的值,就可以计算在log()级别的时间求解出答案。
1 |
int mod; |
函数中间的运算数可能超过int的范围,所以当我们使用时要注意数据范围而选取适当的数据类型(int,long long)。
矩阵快速幂
矩阵快速幂思想和快速幂一样,只不过由单纯的数字运算变成了矩阵运算(这里需要了解矩阵的运算方法)。
使用矩阵快速幂的场合一般为知道递推式,求解相应的第n项的值。
下面以这个式子为样例,来进行矩阵快速幂的讲解。
$$
a_{n}=2*a_{n-1}+1
$$
我们用这个式子构造一个矩阵:
$$
left[
begin{matrix}
a_n \
1
end{matrix}
right]
=
left[
begin{matrix}
2 & 1 \
0 & 1
end{matrix}
right]
*
left[
begin{matrix}
a_{n-1}\
1
end{matrix}
right]
$$
如果没学过矩阵运算的相关知识,可以去百度进行学习。
然后我们继续递推:
$$
left[
begin{matrix}
a_{n-1} \
1
end{matrix}
right]
=
left[
begin{matrix}
2 & 1 \
0 & 1
end{matrix}
right]
*
left[
begin{matrix}
a_{n-2}\
1
end{matrix}
right]
$$
$$
…
$$
$$
left[
begin{matrix}
a_2 \
1
end{matrix}
right]
=
left[
begin{matrix}
2 & 1 \
0 & 1
end{matrix}
right]
*
left[
begin{matrix}
a_{1} \
1
end{matrix}
right]
$$
所以
$$
left[
begin{matrix}
a_n \
1
end{matrix}
right]
=
{left[
begin{matrix}
2 & 1 \
0 & 1
end{matrix}
right]}^{n-1}
*
left[
begin{matrix}
a_{1}\
1
end{matrix}
right]
$$
所以我们只需要求出中间的矩阵的结果就可以求出答案。
其大致步骤和快速幂一样。
1 |
struct node{ |
矩阵乘法也几乎是模板,其难点在于矩阵的构造,给你一个递推式,你必须推出相应的矩阵才可以进行运算,因此需要多学习一些矩阵的知识。
接下来展示一个Fibonacci的递推矩阵:
Fibonacci的定义式:
$$
F(1)=f(2)=1
F(n)=F(n-1)+F(n-2) (n>2)
$$
递推矩阵:
$$
left[
begin{matrix}
F(n)\
F(n-1)
end{matrix}
right]
=
left[
begin{matrix}
1 & 1\
1 & 0
end{matrix}
right]
*
left[
begin{matrix}
F(n-1)\
F(n-2)
end{matrix}
right]
$$
虽然这这个矩阵的第二个运算式子 F( n - 1 )=F( n - 1 ) 看起来是废话,但我们构造矩阵的目的是合理性,只要矩阵符合条件,就可以进行计算。
计算这个式子时需要注意矩阵快速幂的指数。
相关题目可以百度进行搜索。




近期评论