快速幂
求: a b a^{b} ab
int PowerMod(int a, int b, int c)//c为mod值防溢出
{
int ans = 1;
a = a % c;
while(b>0)
{
if(b & 1)
ans = (ans * a) % c;//如果二进制为1则取该值
b = b >> 1;// b=b/2,二进制从右向左遍历
a = (a * a) % c;//相当于二进制的每一位,从右向左变化
}
return ans;
}
复杂度分析
时间复杂度:
O
(
log
n
)
。
O(\log n) 。
O(logn)。
空间复杂度:O(1)。
例子:求
2
11
2^{11}
211。
将11拆成1+2+8,也就是
2
0
+
2
1
+
2
3
2^{0}+2^{1}+2^{3}
20+21+23,在观察11的二进制1011(从右到左观察),说白了就是二进制和十进制间的转换,二进制到十进制,0不起作用 。
a的值:
2
1
−
>
2
2
−
>
2
4
−
>
2
8
−
>
2
16
2^{1} -> 2^{2} ->2^{4}->2^{8}->2^{16}
21−>22−>24−>28−>216
ans的值:
2
1
−
>
2
1
∗
2
2
−
>
2
1
∗
2
2
∗
2
8
2^{1} -> 2^{1}*2^{2} -> 2^{1}*2^{2}*2^{8}
21−>21∗22−>21∗22∗28
力扣: https://leetcode-cn.com/problems/powx-n/
**
快速矩阵幂
**
快速矩阵幂是建立在数的快速幂的基础上的,根据快速幂的原理, 矩阵相乘就是把上边的数字a换成矩阵A,然后再写一个函数,去计算两个矩阵的乘积。 对于数字,初始化为1, 对于矩阵呢,初始化当然是E了,也就是单位矩阵,因为A*E=A。
vector<vector<long>> pow(vector<vector<long>> a, int n){//矩阵n次方
vector<vector<long>> ans{{1,0},{0,1}};
while(n > 0){
if(n & 1)
ans = multiply(ans,a);
n >>= 1;
a = multiply(a,a);
}
return ans;
}
vector<vector<long>> multiply(vector<vector<long>> a, vector<vector<long>> b){//矩阵相乘
vector<vector<long>> c{{0,0},{0,0}};//初始值E
for(int i=0; i < 2; i++){
for(int j=0; j < 2; j++){
c[i][j] = (a[i][0]*b[0][j] + a[i][1]*b[1][j]) % mod;//矩阵相乘公式
}
}
return c;
}
复杂度分析
时间复杂度:
O
(
log
n
)
。
O(\log n) 。
O(logn)。
空间复杂度:O(1)。
力扣:https://leetcode-cn.com/problems/fei-bo-na-qi-shu-lie-lcof/