矩阵专题
#介绍
矩阵有一个神奇的作用,它可以用来快速求递推式的第 n n n项,学会这个技
能,你需要掌握这两个前置芝士 矩阵快速幂,
矩阵加速(数列)
具体怎么优化呢? 这个博客已经总结的较为全面,在这里我就不再加赘述。
代码
贴一发我写的模板
矩阵快速幂
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdio>
#define int long long
#define mod 1000000007
using namespace std;
const int maxn=1e2+10;
int n,k;
inline int read(){
int ret=0;
int f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')
f=-f;
ch=getchar();
}
while(ch<='9'&ch>='0'){
ret=ret*10+(ch^'0');
ch=getchar();
}
return f*ret;
}
struct mat{
int a[maxn][maxn];
mat(){
memset(a,0,sizeof(a));
}
inline void build(){
for(int i=1;i<=n;i++){
a[i][i]=1;
}
}
mat operator *(const mat &b){
mat ans;
for(int k=1;k<=n;++k)
for(int i=1;i<=n;++i)
for(int j=1;j<=n;++j)
ans.a[i][j]=(((ans.a[i][j]%mod+a[i][k]*b.a[k][j]%mod)+mod)%mod);
return ans;
}
void init(){
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++){
a[i][j]=read();
}
}
void out(){
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
cout<<a[i][j]<<" ";
}
cout<<endl;
}
}
};
mat pow(mat x,int y){
mat ans;
ans.build();
while(y){
if(y&1){
ans=ans*x;
}
x=x*x;
y=y>>1;
}
return ans;
}
signed main(){
// freopen("a.txt","r",stdin);
n=read();
k=read();
mat a1;
a1.init();
a1=pow(a1,k);
a1.out();
return 0;
}
矩阵加速
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define int long long
#define mod 1000000007
using namespace std;
const int maxn=1e2+10;
inline int read(){
int ret=0;
int f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')
f=-f;
ch=getchar();
}
while(ch<='9'&ch>='0'){
ret=ret*10+(ch^'0');
ch=getchar();
}
return f*ret;
}
struct mat{
int a[4][4];
mat(){
memset(a,0,sizeof(a));
}
void build(){
for(int i=1;i<=3;i++){
a[i][i]=1;
}
}
mat operator *(const mat &b1){
mat ab;
for(int k=1;k<=3;++k)
for(int i=1;i<=3;++i)
for(int j=1;j<=3;++j)
ab.a[i][j]=(((ab.a[i][j]%mod+a[i][k]*b1.a[k][j]%mod)+mod)%mod);
return ab;
}
void out(){
for(int i=1;i<=3;i++){
for(int j=1;j<=3;j++){
cout<<a[i][j]<<" ";
}
cout<<endl;
}
}
};
int q[maxn];
int b[maxn];
int n;
int an[maxn];
bool cmp(int x,int y){
return q[x]<q[y];
}
mat pow(mat x,int y){
mat ans;
ans.build();
while(y){
if(y&1){
ans=ans*x;
}
x=x*x;
y=y>>1;
}
return ans;
}
mat mul(mat x,mat y){
mat ans;
for(int k=1;k<=3;k++){
for(int i=1;i<=1;i++){
for(int j=1;j<=3;j++){
ans.a[i][j]=(ans.a[i][j]%mod+x.a[i][k]*y.a[k][j]%mod+mod)%mod;
}
}
}
return ans;
}
signed main(){
n=read();
for(int i=1;i<=n;i++){
q[i]=read();
b[i]=i;
}
sort(b+1,b+1+n,cmp);
mat st;
st.a[1][1]=1;
st.a[1][2]=1;
st.a[2][3]=1;
st.a[3][1]=1;
mat ans;
ans.a[1][1]=1;
ans.a[1][2]=1;
ans.a[1][3]=1;
int fla=0;
for(int i=1;i<=n;i++){
if(q[b[i]]<=3){
an[b[i]]=1;
continue;
}
if(fla==0){
ans=mul(ans,pow(st,q[b[i]]-3));
an[b[i]]=ans.a[1][1];
fla=1;
continue;
}
ans=mul(ans,pow(st,q[b[i]]-q[b[i-1]]));
an[b[i]]=ans.a[1][1];
}
for(int i=1;i<=n;i++){
cout<<an[i]<<endl;
}
return 0;
}
最后推荐一道练习题 P1306 斐波那契公约数