标签:long ++ const pac def code 矩阵相乘 构造矩阵 加速
对递归式进行矩阵构造
构造矩阵
\(\left[ \begin{matrix} 1&0&1\\1&0&0\\0&1&0 \end{matrix} \right]\) \(*\left[ \begin{matrix} F_{n}\\F_{n-1}\\F_{n-2} \end{matrix} \right]\)
先令构造矩阵进行矩阵快速幂
\(\left[ \begin{matrix} 1&0&1\\1&0&0\\0&1&0 \end{matrix} \right]^{n}\)
对于欲求矩阵和构造矩阵,如果乘1次
\(\left[ \begin{matrix} 1&0&1\\1&0&0\\0&1&0 \end{matrix} \right]\) \(*\left[ \begin{matrix} F_{n}\\F_{n-1}\\F_{n-2} \end{matrix} \right]\) \(=\left[ \begin{matrix} F_{n+1}\\F_{n}\\F_{n-1} \end{matrix} \right]\)
那么n个构造矩阵和欲求矩阵相乘,就是
\(\left[ \begin{matrix} F_{n+1}\\F_{n}\\F_{n-1} \end{matrix} \right]\)
也就可以得出n个矩阵进行矩阵快速幂,然后与欲求矩阵相乘,最后第2行就是所求值
#include <iostream>
#include <cstdio>
#include <algorithm>
#define rep(i,a,b) for(int i=a;i<b;i++)
#define mod 1000000007
#define ll long long
using namespace std;
const int maxn =1e2+5;
ll n,m,p;
struct Matrix{
ll m[maxn][maxn];
};
Matrix a,e;//a是输入矩阵,e是单位矩阵
Matrix Mul(Matrix a,Matrix b){
Matrix c;
rep(i,1,n+1)rep(j,1,n+1)c.m[i][j]=0;
rep(i,1,n+1)rep(j,1,n+1)rep(k,1,n+1)
c.m[i][j]=c.m[i][j]%mod+a.m[i][k]*b.m[k][j]%mod;
return c;
}
Matrix pow(Matrix x,ll y){
Matrix ans =e;
while(y){
if(y&1)ans=Mul(ans,x);
x=Mul(x,x);
y>>=1;
}
return ans;
}
int main(){
int t;
cin>>t;
while(t--){
ll p;
cin>>p;
n= 3;
rep(i,1,n+1)rep(j,1,n+1)a.m[i][j]=0;
a.m[1][1]=a.m[1][3]=a.m[2][1]=a.m[3][2]=1;
rep(i,1,n+1)e.m[i][i]=1;
Matrix ans = pow(a,p);
printf("%lld\n",ans.m[2][1]%mod);
}
return 0;
}
标签:long ++ const pac def code 矩阵相乘 构造矩阵 加速
原文地址:https://www.cnblogs.com/Emcikem/p/11734684.html