模板 n维矩阵的二分幂
2012-03-23 15:43 javaspring 阅读(195) 评论(0) 编辑 收藏 举报今天一上午一下午就干了点这,就写了一个这样恶心的模板,,写出来我自己都不想看,,不过还好,可以用。。这个模板可以求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; }