@xiaoziyao
2020-06-02T18:41:28.000000Z
字数 6561
阅读 1363
数学
学习笔记
矩阵是一个按照长方阵列排列的复数或实数集合
例如:
在矩阵的乘法中,有一种矩阵起着特殊的作用,如同数的乘法中的1,这种矩阵被称为单位矩阵。
单位矩阵是个方阵,从左上角到右下角的对角线(称为主对角线)上的元素均为1。除此以外全都为0。
例1:斐波那契数列
题意
求斐波那契数列的第项,即,且
暴力做法:时间,空间
开f数组爆算斐波那契数列
例2:【模板】矩阵加速(数列)
题意
给定数组a[],且a[1]=a[2]=a[3]=1,a[i]=a[i-1]+a[i-3],求a[n]
矩阵加速1
我们需要的矩阵为:
#include<stdio.h>
const long long mod=1000000007;
long long i,j,k,m,n,T;
struct matrix{
int len,wid;
long long mt[105][105];
}ans;
matrix mul(matrix a,matrix b){
matrix res;
res.len=a.len,res.wid=b.wid;
for(int u=1;u<=a.len;u++)
for(int v=1;v<=b.wid;v++)
res.mt[u][v]=0;
for(int u=1;u<=a.len;u++)
for(int v=1;v<=b.wid;v++)
for(int w=1;w<=a.wid;w++)
res.mt[u][v]+=(a.mt[u][w]*b.mt[w][v])%mod,res.mt[u][v]%=mod;
return res;
}
long long calc(long long b){
matrix a,res;
a.len=a.wid=3;
a.mt[1][1]=a.mt[1][3]=a.mt[2][1]=a.mt[2][2]=a.mt[3][2]=0;
a.mt[1][2]=a.mt[2][3]=a.mt[3][1]=a.mt[3][3]=1;
res.len=1,res.wid=3;
res.mt[1][1]=res.mt[1][2]=res.mt[1][3]=1;
while(b){
if(b&1)
res=mul(res,a);
a=mul(a,a),b>>=1;
}
return res.mt[1][3];
}
int main(){
scanf("%lld",&T);
while(T--){
scanf("%lld",&n);
if(n<=3){
puts("1");
continue;
}
printf("%lld\n",calc(n-3));
}
return 0;
}
#include<stdio.h>
const long long mod=1000000007;
long long i,j,k,m,n,T;
struct matrix{
int len,wid;
long long mt[105][105];
}ans;
matrix mul(matrix a,matrix b){
matrix res;
res.len=a.len,res.wid=b.wid;
for(int u=1;u<=a.len;u++)
for(int v=1;v<=b.wid;v++)
res.mt[u][v]=0;
for(int u=1;u<=a.len;u++)
for(int v=1;v<=b.wid;v++)
for(int w=1;w<=a.wid;w++)
res.mt[u][v]+=(a.mt[u][w]*b.mt[w][v])%mod,res.mt[u][v]%=mod;
return res;
}
long long calc(long long b){
matrix a,res;
a.len=a.wid=3;
a.mt[1][2]=a.mt[2][2]=a.mt[2][3]=a.mt[3][1]=a.mt[3][3]=0;
a.mt[1][1]=a.mt[1][3]=a.mt[2][1]=a.mt[3][2]=1;
res.len=1,res.wid=3;
res.mt[1][1]=res.mt[1][2]=res.mt[1][3]=1;
while(b){
if(b&1)
res=mul(res,a);
a=mul(a,a),b>>=1;
}
return res.mt[1][1];
}
int main(){
scanf("%lld",&T);
while(T--){
scanf("%lld",&n);
if(n<=3){
puts("1");
continue;
}
printf("%lld\n",calc(n-3));
}
return 0;
}
#include<stdio.h>
const long long mod=1000000007;
long long i,j,k,m,n,T;
struct matrix{
int len,wid;
long long mt[105][105];
}ans;
matrix mul(matrix a,matrix b){
matrix res;
res.len=a.len,res.wid=b.wid;
for(int u=1;u<=a.len;u++)
for(int v=1;v<=b.wid;v++)
res.mt[u][v]=0;
for(int u=1;u<=a.len;u++)
for(int v=1;v<=b.wid;v++)
for(int w=1;w<=a.wid;w++)
res.mt[u][v]+=(a.mt[u][w]*b.mt[w][v])%mod,res.mt[u][v]%=mod;
return res;
}
long long calc(long long n){
long long b=(n-1)/3;
matrix a,res;
a.len=a.wid=3;
a.mt[3][2]=0;
a.mt[1][2]=a.mt[1][3]=a.mt[2][1]=a.mt[2][2]=a.mt[2][3]=a.mt[3][1]=a.mt[3][3]=1;
a.mt[1][1]=2;
res.len=1,res.wid=3;
res.mt[1][1]=res.mt[1][2]=res.mt[1][3]=1;
while(b){
if(b&1)
res=mul(res,a);
a=mul(a,a),b>>=1;
}
return res.mt[1][n%3+1];
}
int main(){
scanf("%lld",&T);
while(T--){
scanf("%lld",&n);
if(n<=3){
puts("1");
continue;
}
printf("%lld\n",calc(n));
}
return 0;
}