只是为了记录个人所学,整理出来防止忘记,大佬勿喷,一般不看评论,怕被喷
整数快速幂
介绍整数快速幂之前先要说明整数的快速幂是什么?如何实现。在本质上整数快速幂和矩阵快速幂是相同的,如果知道整数快速幂的实现和原理,那么现在你需要自己实现矩阵快速幂。
x和y 均为正整数的情况
整数快速幂应该是比较熟悉的 xy ,假设我们需要求x的y次幂,那么一种直观的方法是直接遍历y次。
注意类型之间的转换尤其是go 还有数据的范围,一般都会 %mod
c++
long long multiply(int x,int y){
long long ans=1;
while(y--){
ans*=(long long)x;
}
return ans;
}
go
func multiply(x, y int64) (ans int64) {
ans = 1
for ; y > 0; y-- {
ans *= x
}
return
}
显然这样会浪费很多时间,那么我们可以找到一个快速的方法:
我们可以发现任意整数,可以表示为 一系列的2的指数的和 如:11 = 20 + 21 + 23 ,而11的二进制位 1011, 上式中的 0 1 3 正好与二进制位中的 1 的位置相对应(1011 对应的2的权重分别位8(23) 4(22) 2(21) 1)(20) )。我们举个例子,需要求 311 ,而 311 = 31 * 32 * 38 ,在计算311的时候就可以分别计算 31 *,32 , 38 然后相乘,可以观察到 11 的二进制为 1011 ,正好是对应的。
c++
double quickMul(double x, long long n) {
double ans = 1.0,base = x;
while (n > 0) {
if (n & 1) {
ans *= base;
}
base *= base;
n /= 2;
}
return ans;
}
go
func quickMul(x float64, n int) float64 {
var ans float64 = 1
var base float64 = x
for ; n > 0; n /= 2 {
if n&1 == 1 {
ans = (ans * base)
}
base = (base * base)
}
return ans
}
表述不太好,贴个链接 leetcode power(x,n)
矩阵快速幂
c++
using ll=long long;
const long long mod=1e9+7;
vector<vector<ll>> multiply(vector<vector<ll>> &a,vector<vector<ll>> &b){
int n=a.size(),m=b[0].size(),t=b.size();
vector<vector<ll>> ans(n,vector<ll>(m));
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
for(int k=0;k<t;k++){
ans[i][j]=(ans[i][j]+(a[i][k]*b[k][j])%mod)%mod;
}
}
}
return ans;
}
vector<vector<ll>> fastPow(vector<vector<ll>> &a,int n){
int size=a.size();
vector<vector<ll>> ans(size,vector<ll>(size));
for(int i=0;i<size;i++){
ans[i][i]=1;
}
vector<vector<ll>> base=a;
while(n){
if(n&1){
ans=multiply(ans,base);
}
n>>=1;
base=multiply(base,base);
}
return ans;
}
go
const mod int = 1e9 + 7
type matrix [][]int
func (a matrix) mul(b *matrix) matrix {
n := len(a)
m := len((*b)[0])
ans := make(matrix, n)
for i, row := range a {
ans[i] = make([]int, m)
for j := range (*b)[0] {
for k, v := range row {
ans[i][j] = (ans[i][j] + v*(*b)[k][j]) % mod
}
}
}
return ans
}
func (a matrix) pow(n int) matrix {
l := len(a)
res := make(matrix, l)
for i := range res {
res[i] = make([]int, l)
res[i][i] = 1
}
for ; n > 0; n >>= 1 {
if n&1 > 0 {
res = res.mul(&a)
}
a = a.mul(&a)
}
return res
}
有个例题 leetcode 1220