今天一上午一下午就干了点这,就写了一个这样恶心的模板,,写出来我自己都不想看,,不过还好,可以用。。这个模板可以求n维矩阵的二分幂,主要适用于递推式求值的题目。。
代码:
#include <iostream>
#include <cstdio>
#include <string.h>
using namespace std;
typedef long long ll;
const ll MAX=1000007;
const int row=3;//矩阵的维数,根据题目要求改变
ll aa[11][11],bb[11][11];//aa,bb存储矩阵
ll cc[11][11];//结果矩阵
ll dd[11][11];//单位矩阵
ll mi;//多少次方
class matrix{
public:
void input(ll f[11],ll num[11]);
void initmatrix(ll p[11],ll q[11]);
void matrixmi(int x);//矩阵幂
void matrixfun(ll a[11][11],ll b[11][11]);//矩阵乘积
};
void matrix::input(ll f[11],ll num[11]){
//输入前几项
for(int i=1;i<row;++i){
scanf("%lld",&f[i]);
}
//输入前几项对应的系数
for(int i=1;i<=row;++i){
scanf("%lld",&num[i]);
}
//输入所求的n次方
scanf("%lld",&mi);
}
//构造矩阵
void matrix::initmatrix(ll ff[11],ll a[11]){
memset(aa,0,sizeof(aa));
memset(bb,0,sizeof(bb));
//构造单位矩阵
for(int i=1;i<=row;++i){
for(int j=1;j<=row;++j)
dd[i][j]=0;
dd[i][i]=1;
}
for(int i=1;i<row;++i)
aa[1][i]=ff[i];
aa[1][row]=a[row];//原矩阵
for(int i=1;i<=row-2;++i)
bb[i+1][i]=1;
bb[row][row]=1;bb[row][row-1]=1;
for(int i=1;i<row;++i)
bb[i][row-1]=a[i];//构造所要乘的矩阵
}
//矩阵乘法
void matrix::matrixfun(ll a[11][11],ll b[11][11]){
long long sum=0;
memset(cc,0,sizeof(cc));
for(int i=1;i<=row;++i){
for(int j=1;j<=row;++j){
sum=0;
for(int k=1;k<=row;++k)
sum+=(a[i][k]*b[k][j]);
cc[i][j]=(sum%MAX);
}
}
}
//矩阵二分幂
void matrix::matrixmi(int x){
while(x){
if(x&1){
matrixfun(dd,bb);
for(int i=1;i<=row;++i)
for(int j=1;j<=row;++j)
dd[i][j]=cc[i][j];
}
matrixfun(bb,bb);
for(int i=1;i<=row;++i)
for(int j=1;j<=row;++j)
bb[i][j]=cc[i][j];
x=x>>1;
}
matrixfun(aa,dd);
}
int main(){
int numcase;
scanf("%d",&numcase);
while(numcase--){
matrix mm;
ll f[11],num[11];
mm.input(f,num);
if(mi<row){
cc[1][row-1]=f[mi]%MAX;
}
else{
mm.initmatrix(f,num);
mm.matrixmi(mi-2);
}
if(cc[1][row-1]>0)
printf("%lld\n",cc[1][row-1]);
else
printf("%lld\n",cc[1][row-1]+MAX);
}
return 0;
}