矩阵快速幂和矩阵加速

矩阵快速幂

先贴一下快速幂的板子

void ksm(int a, int k) { // a^k
	int res;
	while (k) {
		if (k & 1) res *= a;
		k >>= 1;
		a *= a;
	}
	return res;
} 

众所周知,矩阵乘法的公式是

C i , j = ∑ k = 1 n b i , k × c k , j C_{i,j} = \sum_{k=1}^n b_{i,k} \times c_{k,j} Ci,j=k=1nbi,k×ck,j

所以写个矩阵的结构体,和乘法的函数,套进快速幂就行了。时间复杂度 O ( n 3 log ⁡ k ) O(n^3 \log k) O(n3logk)

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 100 + 5, INF = 0x3f3f3f3f, mod = 1e9 + 7;
inline int read() {
	int x = 0, f = 0; char ch = 0;
	while (!isdigit(ch)) f |= ch == '-', ch = getchar();
	while (isdigit(ch)) x = (x << 3) + (x << 1) + (ch ^ 48), ch = getchar();
	return f ? -x : x;
}
int n;
struct mat {
	int m[N][N];
	mat() {
		memset(m, 0, sizeof(m));
		for (int i = 0; i < N; i++) m[i][i] = 1;
	}
};


mat mul(mat a, mat b) {
	mat c;
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= n; j++) {
			c.m[i][j] = 0; //Mention! 
			for (int k = 1; k <= n; k++) 
				c.m[i][j] += a.m[i][k] * b.m[k][j] % mod;
			c.m[i][j] %= mod;	
		}
	return c;
}
mat ksm(mat a, int k) {
	mat res;
	while (k) {
		if (k & 1) res = mul(res, a);
		k >>= 1;
		a = mul(a, a);
	}
	return res;
}
signed main() {
	n = read(); int k = read();
	
	mat a; 
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= n; j++)
			a.m[i][j] = read();
	mat ans = ksm(a, k);
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= n; j++)
			printf("%lld ", ans.m[i][j]);
		puts("");
	}		
	return 0;
}

【模板】矩阵加速

已知一个数列 a a a,它满足
a x = { 1 x ∈ { 1 , 2 , 3 } a x − 1 + a x − 3 x ≥ 4 a_{x}=\left\{\begin{array}{ll} 1 & x \in\{1,2,3\} \\ a_{x-1}+a_{x-3} & x \geq 4 \end{array}\right. ax={1ax1+ax3x{1,2,3}x4
a a a 数列的第 n n n 项对 1 0 9 + 7 10^{9}+7 109+7 取余的值。

已知 f i − 1 , f i − 2 , f i − 3 f_{i-1},f_{i-2},f_{i-3} fi1,fi2,fi3 发现可以推出 f i , f i + 1 , f i + 2 f_{i}, f_{i+1}, f_{i+2} fi,fi+1,fi+2

那么有

[ f i f i + 1 f i + 2 ] = [ f i − 1 f i − 2 f i − 3 ] × [ ? ? ? ? ? ? ? ? ? ] \begin{bmatrix} f_i &f_{i+1} & f_{i+2} \end{bmatrix}= \begin{bmatrix} f_{i-1} &f_{i-2} & f_{i-3} \end{bmatrix} \times \begin{bmatrix} ? & ? & ? \\ ? & ? & ? \\ ? & ? & ? \end{bmatrix} [fifi+1fi+2]=[fi1fi2fi3]×?????????

根据递推式

{ f i = 1 × f i − 1 + 0 × f i − 2 + 1 × f i − 3 f i + 1 = f i + f i − 2 = 1 × f i − 1 + 1 × f i − 2 + 1 × f i − 3 f i + 2 = f i + 1 + f i − 1 = 2 × f i − 1 + 1 × f i − 2 + 1 × f i − 3 \begin{cases} f_{i} = 1 \times f_{i-1} + 0 \times f_{i-2} + 1 \times f_{i-3} \\ f_{i+1} = f_{i} + f_{i-2} = 1 \times f_{i-1} + 1 \times f_{i-2} + 1 \times f_{i-3} \\ f_{i+2} = f_{i+1} + f_{i-1} = 2 \times f_{i-1} + 1 \times f_{i-2} + 1 \times f_{i-3} \end{cases} fi=1×fi1+0×fi2+1×fi3fi+1=fi+fi2=1×fi1+1×fi2+1×fi3fi+2=fi+1+fi1=2×fi1+1×fi2+1×fi3

竖着写,用来加速的矩阵为

[ 1 1 2 0 1 1 1 1 1 ] \begin{bmatrix} 1 & 1 & 2\\ 0 & 1 & 1\\ 1 & 1 & 1\\ \end{bmatrix} 101111211

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值