【原创】矩阵乘法 矩阵快速幂 矩阵加速 矩阵优化dp

矩阵

说在前面

数论复习……
数论学习 Part 4。

矩阵乘法

举个例子就过。
在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

所以结果是 [ 1 2 3 2 3 4 ] × [ 1 2 3 4 5 6 ] = [ 22 28 31 40 ] \begin{bmatrix} 1 & 2 & 3 \\ 2 & 3 & 4\\ \end{bmatrix} \times \begin{bmatrix} 1 & 2 \\ 3&4\\5&6\end{bmatrix}=\begin{bmatrix} 22 & 28\\ 31 & 40 \\ \end{bmatrix} [122334]×135246=[22312840]

必须是 i ∗ k i*k ik k ∗ j k*j kj的矩阵相乘。
注意没有交换律, i ∗ i i*i ii i ∗ i i*i ii相乘也不行。

就第一个矩阵的第 i i i行点乘上第二个矩阵的第 j j j列得到答案矩阵的第 ( i , j ) (i,j) (i,j)项。
时间复杂度 Θ ( n 3 ) \Theta(n^3) Θ(n3),据说有 Θ ( n 2.7 ) \Theta(n^{2.7}) Θ(n2.7)的,但我不会,Alster大佬也不会。

矩阵快速幂

就普通的快速幂。

代码如下:

#define ll long long
const int MAXN=102,mod=1e9+7;
struct matrix
{
	int n,m;ll arr[MAXN][MAXN];
	matrix(){n=m=0,memset(arr,0,sizeof arr);}
	void out(){for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) printf("%lld%s",arr[i][j],j==m?"\n":" ");}
	matrix operator * (const matrix &p) const
	{
		matrix ans; ans.n=n,ans.m=p.m;
		for(int i=1;i<=n;i++)
			for(int j=1;j<=p.m;j++)
				for(int k=1;k<=m;k++)
					(ans.arr[i][j]+=arr[i][k]*p.arr[k][j]%mod)%=mod;
		return ans;
	}
}ip,op;

matrix ksm(matrix a,ll b)
{
	matrix ans;
	ans.n=ans.m=a.n;
	for(int i=1;i<=a.n;i++) ans.arr[i][i]=1;
	while(b)
	{
		if(b&1) ans=ans*a;
		a=a*a,b>>=1;
	}
	return ans;
}

矩阵加速

方程满足 f ( n ) = f ( n − 1 ) × p ( 1 ) + f ( n − 2 ) × p ( 2 ) + ⋯ + f ( n − k ) × p ( k ) f(n)=f(n−1)\times p(1)+f(n−2)\times p(2)+\cdots+f(n−k)\times p(k) f(n)=f(n1)×p(1)+f(n2)×p(2)++f(nk)×p(k)
这用递推是 Θ ( n ) \Theta(n) Θ(n)的时间复杂度。

因为标题叫做矩阵加速,所以我们设矩阵 F ( n ) = [ f [ n − k + 1 ] f [ n − k + 2 ] ⋮ f [ n − 2 ] f [ n − 1 ] f [ n ] ] F(n)=\begin{bmatrix} f[n-k+1] \\ f[n-k+2] \\ \vdots \\ f[n-2]\\f[n-1]\\f[n]\end{bmatrix} F(n)=f[nk+1]f[nk+2]f[n2]f[n1]f[n],来递推这个矩阵,并且期待能把递推式写成非常好看的亚子,比如说等比数列然后直接矩阵快速幂。

既然如此我们肯定要求出一个 k ∗ k k*k kk的矩阵 A A A,使得 F [ n ] = A ∗ F [ n − 1 ] F[n]=A*F[n-1] F[n]=AF[n1]。那么我们就得让 F [ n ] F[n] F[n]的最后一项( f [ n ] f[n] f[n])等于 f ( n − 1 ) × p ( 1 ) + f ( n − 2 ) × p ( 2 ) + ⋯ + f ( n − k ) × p ( k ) f(n-1)\times p(1)+f(n-2)\times p(2)+\cdots+f(n-k)\times p(k) f(n1)×p(1)+f(n2)×p(2)++f(nk)×p(k),这一串乘积中的 f f f就是 F [ n − 1 ] F[n-1] F[n1],那么那些 p p p的系数就一定是 A A A的最后一行。

A = [ ? ? ? ⋯ ? ? ? ? ⋯ ? ? ? ? ⋯ ? ⋮ ⋮ ⋮ ⋱ ⋮ p ( k ) p ( k − 1 ) p ( k − 2 ) ⋯ p ( 1 ) ] A=\begin{bmatrix} ? & ? & ? & \cdots & ?\\ ? & ? & ? & \cdots & ?\\ ? & ? & ? & \cdots & ?\\ \vdots & \vdots & \vdots & \ddots & \vdots \\ p(k) & p(k-1) & p(k-2) &\cdots & p(1) \end{bmatrix} A=???p(k)???p(k1)???p(k2)???p(1)

继续, F [ n ] F[n] F[n]的倒数第二项( f [ n − 1 ] f[n-1] f[n1])肯定要把 F [ n − 1 ] F[n-1] F[n1]的最后一项( f [ n − 1 ] f[n-1] f[n1])搞到手,那么 A A A的倒数第二行就会是:除了最后一个数是1以外其他全是零,这样, F [ n − 1 ] F[n-1] F[n1]的其他项都乘上0,只有 f [ n − 1 ] f[n-1] f[n1]乘了1加到了 F [ n ] F[n] F[n]的倒数第二项中。
依次类推,易知 A = [ 0 1 0 ⋯ 0 0 0 1 ⋯ 0 0 0 0 ⋯ 0 ⋮ ⋮ ⋮ ⋱ ⋮ 0 0 0 ⋯ 1 p ( k ) p ( k − 1 ) p ( k − 2 ) ⋯ p ( 1 ) ] F [ n ] = A × F [ n − 1 ] A=\begin{bmatrix} 0 & 1 & 0 & \cdots & 0\\ 0 & 0 & 1 & \cdots & 0\\ 0 & 0 & 0 & \cdots & 0\\ \vdots & \vdots & \vdots & \ddots & \vdots \\ 0 & 0 & 0 & \cdots & 1\\ p(k) & p(k-1) & p(k-2) &\cdots & p(1) \end{bmatrix}\\ F[n]=A\times F[n-1] A=0000p(k)1000p(k1)0100p(k2)0001p(1)F[n]=A×F[n1]

然后就等比数列了,然后就矩阵快速幂了。

如果有常数或者是常数的若干次方那就在 F [ n ] F[n] F[n]里面多开一项常数,常数就转移给常数 F [ n − 1 ] [ n ] = f [ n − 1 ] → F [ n ] [ n − 1 ] = f [ n − 1 ] F[n-1][n]=f[n-1]\to F[n][n-1]=f[n-1] F[n1][n]=f[n1]F[n][n1]=f[n1], F [ 0 ] → F [ 0 ] F[0]\to F[0] F[0]F[0]

再比如说POJ 3233,给定矩阵 A A A和数 k k k,求 A 1 + A 2 + A 3 + ⋯ + A k A^1+A^2+A^3+\cdots+A^k A1+A2+A3++Ak
S k = A 1 + A 2 + A 3 + ⋯ + A k S_k=A^1+A^2+A^3+\cdots+A^k Sk=A1+A2+A3++Ak,则有 S k = S k − 1 + A k S_k=S_{k-1}+A^k Sk=Sk1+Ak
据说可以二分。
不考虑二分,考虑矩阵加速 。

F [ k ] = [ S k A k ] = [ S k − 1 + A k A k − 1 × k ] = [ E A O A ] × [ S k − 1 A k − 1 ] E 是 单 位 矩 阵 , O 是 零 矩 阵 F[k]=\begin{bmatrix} S_k\\A^k\end{bmatrix}=\begin{bmatrix} S_{k-1}+A^{k}\\A^{k-1}\times k\end{bmatrix}=\begin{bmatrix} E & A\\O & A\end{bmatrix}\times \begin{bmatrix} S_{k-1}\\A^{k-1}\end{bmatrix}\\ E是单位矩阵,O是零矩阵 F[k]=[SkAk]=[Sk1+AkAk1×k]=[EOAA]×[Sk1Ak1]EO

考场上随缘发挥吧。

参考文献

好题好讲解
i n   f a c t   头 像 好 看 \xcancel{\small in~fact~头像好看} in fact  言简意赅,虽然有错

一头好纯人,说有一这个,路像太看了。
在这里插入图片描述

教练,我想学画这个

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值