矩阵快速幂

只是为了记录个人所学,整理出来防止忘记,大佬勿喷,一般不看评论,怕被喷

整数快速幂

介绍整数快速幂之前先要说明整数的快速幂是什么?如何实现。在本质上整数快速幂和矩阵快速幂是相同的,如果知道整数快速幂的实现和原理,那么现在你需要自己实现矩阵快速幂。
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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值