矩阵快速幂

先来回顾一下整数快速幂的代码:

public static long qmi(long b, int i,int mod) {
		long ans=1;
		for(;i>0;i>>=1,b=b*b%mod)if((i&1)==1)ans = ans * b % mod;
		return ans;
}

(注意如果要对底数取模,注意底数是否可能是负数。如果可能是的话,取模函数写作如下形式:

static int ff(int x,int m) {
		return (x%m+m)%m;
}

整数快速幂,是用来计算AB %C的,时间复杂度在O(logB)以内(每次的位运算相当于把余下的B折半)。当然,还可以用快速乘来进一步优化。

矩阵快速幂,就是将整数A变为常数矩阵A。有什么用呢?
第一步,列出第n项递推式f(n)=f(n-1)+f(n-2)
第二步,建立矩阵递推式,找到转移矩阵
在这里插入图片描述
简写成T*A(n-1)=A(n),
在这里插入图片描述
T矩阵就是转移矩阵,而且一定是一个常数矩阵,
由此得到A(n)=Tn-1 *A(1)
计算Tn-1 的工作就可以交给矩阵快速幂了,A(1)手动计算,就可以得到A(n)了。

基础知识:
(1)矩阵乘法
在这里插入图片描述
其中c[i][j]为A的第i行与B的第i列的乘积的和,即在这里插入图片描述

矩阵乘法时间复杂度O(n3)
矩阵乘法前提是A的行数等于B的列数(可见矩阵乘法不满足交换律),但是如果是方阵则不存在这个问题。
矩阵快速幂的代码,就是把乘法改成矩阵乘法,呈上:
一些简单的递推式
1.f(n)=af(n-1)+bf(n-2)+c;(a,b,c是常数)
在这里插入图片描述
2.f(n)=c^n-f(n-1) ;(c是常数)
在这里插入图片描述

矩阵快速幂板子:

public class Main {
	static int maxn=10,mod=1000000007;
	static class Matrix{
		long m[][]=new long[maxn][maxn];
	}
	static Matrix multi(Matrix a,Matrix b,int N) {//N为T方阵阶数,下同
		Matrix ans=new Matrix();
		for(int i=0;i<N;i++)
			for(int j=0;j<N;j++)
				for(int k=0;k<N;k++) {
					ans.m[i][j]+=a.m[i][k]*b.m[k][j]%mod;
					ans.m[i][j]%=mod;
				}
		return ans;
	}
	static Matrix qmi_m(Matrix a,int n,int N) {
		Matrix ans=new Matrix();
		for(int i=0;i<N;i++) {
			ans.m[i][i]=1;
		}
		while(n>0) {
			if((n&1)>0) {
				ans=multi(ans,a,N);
			}
			a=multi(a,a,N);
			n>>=1;
		}
		return ans;
	}
	static long qmi(long b, int i,int mod) {
		long ans=1;
		for(;i>0;i>>=1,b=b*b%mod)if((i&1)==1)ans = ans * b % mod;
		return ans;
	}
	public static void main(String args[]) {
		Matrix T=new Matrix();
		//不要忘记初始化T
		Matrix res=qmi_m(T,n-1,N);
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值