矩阵快速幂【模板】

链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
 

题目描述

已知数列f(n) f(n)\spacef(n)  满足 f(0) =x,f(1)=y,f(n)=af(n−1)+bf(n−2)f(0)\space = x, f(1)=y, f(n)=af(n-1)+bf(n-2)f(0) =x,f(1)=y,f(n)=af(n−1)+bf(n−2)。

输入x,y,a,b,n, 求f(n)对109+710^9+7109+7取模的结果。

输入描述:

 

第一行输入一个整数T,表示T组测试用例。

接下来T行,每行5个数,x,y,a,b,n

1≤T≤1041 \le T \le 10^41≤T≤104
0≤x,y,a,b≤1090 \le x,y,a,b \le 10^90≤x,y,a,b≤109
0≤n≤10180 \le n \le 10^{18}0≤n≤1018

输出描述:

输出T行,每行一个答案。

输入:

7
0 1 1 1 0
0 1 1 1 1
0 1 1 1 2
0 1 1 1 3
0 1 1 1 4
0 1 1 1 5
3 4 5 6 3

输出:

0
1
1
2
3
5
214

答案:

#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 1e3 + 10;
const ll mod = 1e9 + 7;
ll x, y, a, b, n;
struct M{
	ll a[3][3];
	M(){
		memset(a, 0, sizeof(a));
	}
}dis, ans;

void init(){//创建单位矩阵以及如快速幂一样的不断叠加的矩阵
	dis.a[1][1] = a; dis.a[1][2] = 1;
	dis.a[2][1] = b; dis.a[2][2] = 0;
    ans.a[1][1] = (a * y + b * x) % mod;
	ans.a[1][2] = ans.a[2][1] = y; ans.a[2][2] = x;
}
M getM(M x, M y){//矩阵的计算方法
	M temp;
	for(int i = 1; i <= 2; i++){
		for(int j = 1;j <= 2; j++){
			for(int k = 1; k <= 2; k++){
				temp.a[i][j] = (temp.a[i][j] + x.a[i][k] * y.a[k][j]) % mod;
			}
		}
	}
	return temp;
}
void power(ll p){//幂级计算判断为奇数相当于转化为二进制右移
	while(p){
		if(p % 2 == 1){
			ans = getM(ans, dis);
		}
		p /= 2;
		dis = getM(dis, dis);
		
	}
}

int main(){
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	int t; cin >> t;
	while(t--){
		cin >> x >> y >> a >> b >> n;
        init();
        power(n);
        cout << ans.a[2][2] << '\n';
	}
	return 0;
}

解释{ai}

矩阵快速幂是一种高效的算法,用于计算矩阵的高次方,其时间复杂度从朴素的O(n)降低到O(logn)。这种算法在解决一些递推关系、动态规划等问题时非常有用,特别是在需要频繁进行矩阵乘法操作时。以下是对矩阵快速幂的详细解释:

一、基本概念

矩阵快速幂是用来高效地计算矩阵的高次方的算法。在常规方法中,计算一个矩阵的n次方需要连续乘以该矩阵n-1次,但这种方法的时间复杂度较高。矩阵快速幂通过利用矩阵乘法的结合律,将计算过程优化为对数时间复杂度。

二、基本原理

矩阵快速幂的基本原理与整数快速幂类似,都是利用分治的思想。在整数快速幂中,我们将指数表示为二进制形式,然后利用指数的每一位来决定是否将当前的底数乘以自己(即平方操作),并相应地更新指数。在矩阵快速幂中,我们将这个过程应用到矩阵上,即将矩阵的幂次操作转化为矩阵的乘法操作。

具体来说,我们可以将矩阵的n次方表示为一系列矩阵乘法的结果。首先,我们将n表示为二进制形式,然后从最低位开始,依次判断每一位是否为1。如果某一位为1,则将当前的矩阵(初始时为原矩阵或单位矩阵)乘以该矩阵的相应次方(通过之前的计算得到)。然后,将当前的矩阵平方(即乘以自己),并将指数右移一位(即去掉最低位)。这个过程一直持续到指数为0为止。

三、算法步骤

  1. 初始化:将结果矩阵初始化为单位矩阵(如果n为0,则直接返回单位矩阵)。
  2. 二进制分解:将n表示为二进制形式。
  3. 循环计算:从最低位开始遍历n的二进制表示中的每一位。
    • 如果当前位为1,则将结果矩阵乘以原矩阵的相应次方(通过之前的计算得到)。
    • 将原矩阵平方(即乘以自己)。
    • 将指数右移一位(即去掉最低位)。
  4. 返回结果:当指数为0时,循环结束,返回结果矩阵。

四、注意事项

  1. 矩阵大小:矩阵快速幂通常用于方阵(即行数和列数相等的矩阵)。如果矩阵不是方阵,可能需要通过添加零行或零列来将其转换为方阵。
  2. 取模运算:在计算过程中,如果涉及到大数运算,可能需要使用取模运算来防止整数溢出。这通常需要在矩阵乘法函数中进行处理。
  3. 精度问题:在浮点数运算中,矩阵快速幂可能会受到精度问题的影响。因此,在需要高精度结果时,应使用整数或高精度库来进行计算。

五、应用示例

矩阵快速幂在解决斐波那契数列等递推关系问题时非常有用。通过构造一个特定的矩阵,我们可以将递推关系转化为矩阵的幂次运算,然后利用矩阵快速幂来快速求解。此外,矩阵快速幂还可以用于求解线性方程组、图论中的路径计数等问题。

总之,矩阵快速幂是一种高效的算法,它通过利用矩阵乘法的结合律和分治的思想,将矩阵的高次方运算的时间复杂度降低到对数级别。这种算法在解决一些递推关系、动态规划等问题时具有广泛的应用价值。

 

 

 

  • 11
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值