矩阵
说在前面
数论复习……
数论学习 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
i∗k和
k
∗
j
k*j
k∗j的矩阵相乘。
注意没有交换律,
i
∗
i
i*i
i∗i与
i
∗
i
i*i
i∗i相乘也不行。
就第一个矩阵的第
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(n−1)×p(1)+f(n−2)×p(2)+⋯+f(n−k)×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[n−k+1]f[n−k+2]⋮f[n−2]f[n−1]f[n]⎦⎥⎥⎥⎥⎥⎥⎥⎤,来递推这个矩阵,并且期待能把递推式写成非常好看的亚子,比如说等比数列然后直接矩阵快速幂。
既然如此我们肯定要求出一个 k ∗ k k*k k∗k的矩阵 A A A,使得 F [ n ] = A ∗ F [ n − 1 ] F[n]=A*F[n-1] F[n]=A∗F[n−1]。那么我们就得让 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(n−1)×p(1)+f(n−2)×p(2)+⋯+f(n−k)×p(k),这一串乘积中的 f f f就是 F [ n − 1 ] F[n-1] F[n−1],那么那些 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(k−1)???⋮p(k−2)⋯⋯⋯⋱⋯???⋮p(1)⎦⎥⎥⎥⎥⎥⎤
继续,
F
[
n
]
F[n]
F[n]的倒数第二项(
f
[
n
−
1
]
f[n-1]
f[n−1])肯定要把
F
[
n
−
1
]
F[n-1]
F[n−1]的最后一项(
f
[
n
−
1
]
f[n-1]
f[n−1])搞到手,那么
A
A
A的倒数第二行就会是:除了最后一个数是1以外其他全是零,这样,
F
[
n
−
1
]
F[n-1]
F[n−1]的其他项都乘上0,只有
f
[
n
−
1
]
f[n-1]
f[n−1]乘了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=⎣⎢⎢⎢⎢⎢⎢⎢⎡000⋮0p(k)100⋮0p(k−1)010⋮0p(k−2)⋯⋯⋯⋱⋯⋯000⋮1p(1)⎦⎥⎥⎥⎥⎥⎥⎥⎤F[n]=A×F[n−1]
然后就等比数列了,然后就矩阵快速幂了。
如果有常数或者是常数的若干次方那就在 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[n−1][n]=f[n−1]→F[n][n−1]=f[n−1], 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=Sk−1+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]=[Sk−1+AkAk−1×k]=[EOAA]×[Sk−1Ak−1]E是单位矩阵,O是零矩阵
考场上随缘发挥吧。
参考文献
好题好讲解
i
n
f
a
c
t
头
像
好
看
\xcancel{\small in~fact~头像好看}
in fact 头像好看
言简意赅,虽然有错
一头好纯人,说有一这个,路像太看了。
教练,我想学画这个