前置知识:
矩阵乘法
快速幂
矩阵快速幂
实际上就是将快速幂中所有乘法换成矩阵乘法即可。
struct matrix{
ll e[N+11][N+11];
int row,col;
matrix(){
row=col=e[1][1]=1;
}
matrix(int p){
row=col=p;
register int i,j;
for(i=1;i<=p;i++)
for(j=1;j<=p;j++)
e[i][j]=0;
for(register int i=1;i<=p;i++)
e[i][i]=1;
}
matrix(int R,int C){
row=R,col=C;
register int i,j;
for(i=1;i<=R;i++)
for(j=1;j<=C;j++)
e[i][j]=0;
}
void operator = (const matrix B){
row=B.row ,col=B.col ;
register int i,j;
for(i=1;i<=row;i++)
for(j=1;j<=col;j++)
e[i][j]=B.e[i][j];
}
inline ll at(int r,int c){
return e[r][c];
}
inline void edit(int r,int c,ll k){
e[r][c]=k;
}
inline void add_node(int r,int c,ll k){
e[r][c]=(e[r][c]+k)%mod;
}
};
inline matrix mul(matrix A,matrix B)
{
int n=A.row ,m=B.col ,p=B.row ;
matrix C(n,m);
register int i,j,k;
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
for(k=1;k<=p;k++)
C.add_node(i,j,A.at(i,k)*B.at(k,j)%mod);
return C;
}
inline matrix fast_pow(matrix A,ll B)
{
matrix ans(A.row );
while(B>0)
{
if(B%2==1)ans=mul(ans,A);
A=mul(A,A),B>>=1;
}
return ans;
}
\(\text{Fibonacci}\)数列
看这里:https://www.luogu.org/problemnew/show/P1962
对于 100% 的数据: n在long long(INT64)范围内。
一看就不能用一般的递推。
所以我们考虑用矩阵。
\(\begin{bmatrix}F_{n+1}\\F_n\end{bmatrix}\)
我们令其为目标状态C
。
而\(C\)可以由\(\begin{bmatrix}F_{n}\\F_{n-1}\end{bmatrix}(B)\)推过来。
怎么推?
如果\(C=A\times B\),那么\(A\)就是一个\(2\times 2\)的方阵。
根据定义,易知:
F[n+1]=F[n]*1+F[n-1]*1;
F[n]=F[n]*1+F[n-1]*0;
结合矩阵乘法的规则,我们有了以下结论:
\[\begin{bmatrix}F_{n+1}\\F_n\end{bmatrix}=\begin{bmatrix}1&1\\1&0\end{bmatrix} \times \begin{bmatrix}F_{n}\\F_{n-1}\end{bmatrix}\]
所以:
\[\begin{bmatrix}F_{n}\\F_{n-1}\end{bmatrix}=\begin{bmatrix}1&1\\1&0\end{bmatrix}^{n-2} \times \begin{bmatrix}1\\1\end{bmatrix}\]
Luogu P1939 【模板】矩阵加速(数列)
HERE:https://www.luogu.org/problemnew/show/P1939
题意:定义递推式\(x_n\):
\[x_1=x_2=x_3=1\]
\[x_n=x_{n-3}+x_{n-1}(n>3)\]
我们可以仿照上面Fibonacci数列的推导方式做这道题。
定义目标矩阵\(C=\begin{bmatrix} x_n\\x_{n-1}\\x_{n-2} \end{bmatrix}\)
前一个状态\(B=\begin{bmatrix} x_{n-1}\\x_{n-2}\\x_{n-3} \end{bmatrix}\)
\(C\)中的\(x_{n-1},x_{n-2}\)都可以直接从\(B\)中获取。
而\(x_n\)项根据递推式计算即可。
所以,转移矩阵\(A(3\times 3)\)和递推公式就可以得出来了:
\[\begin{bmatrix}x_{n}\\x_{n-1}\\x_{n-2}\end{bmatrix}=\begin{bmatrix}1&0&1\\1&0&0\\0&1&0\end{bmatrix}^{n-3} \times \begin{bmatrix}1(a_3)\\1(a_2)\\1(a_1)\end{bmatrix}\]
[NOI2012]随机数生成器
HERE :https://www.luogu.org/problemnew/show/P2044
题意:定义递推式\(X_n\):
\[X_n=(aX_{n-1}+c)\mod m(n\in[1,10^{18}],n\in\mathbb{Z}^+)\]
然而并不难。
易知第\(n\)项是由第\(n-1\)项推来的。
不妨设\(C=\begin{bmatrix}X_n\\c\end{bmatrix},B=\begin{bmatrix}X_{n-1}\\c\end{bmatrix}\)。
首先,\(C\)中的\(X_n\)项可由递推式得到。
所以:
X[n]=a*X[n-1]+1*c;
c=0*X[n-1]+1*c;
\(\therefore A=\begin{bmatrix}a&1\\0&1\end {bmatrix}\)
最终结论:
\[\begin{bmatrix}X_n\\c\end{bmatrix}=\begin{bmatrix}a&1\\0&1\end {bmatrix}^{n}\times\begin{bmatrix}X_{0}\\c\end{bmatrix}\]