这道题题意是比较简单的,方法也很容易想,构建矩阵,主要难度在构建矩阵的地方。由于A(n)=x*A(n-1)+Y*(n-2),因此可以把A(n)平方,再由S(n)=S(n-1)+A(n)*A(n),所以可以构建矩阵{A(n-2)*A(n-2),A(n-1)*A(n-1),A(n-1)*A(n-2),S(n-1)},{A(n-1)*A(n-1),A(n)*A(n),A(n-1)*A(n),S(n)},构建出矩阵之后就很容易了。。题目:
2 1 1 3 2 3
6 196
#include <iostream> #include <cstdio> #include <string.h> using namespace std; typedef long long ll; const ll MAX=10007; const int row=5;//矩阵的维数,根据题目要求改变 ll aa[11][11],bb[11][11];//aa,bb存储矩阵 ll cc[11][11];//结果矩阵 ll dd[11][11];//单位矩阵 ll mi,x,y;//多少次方 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::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];//原矩阵 bb[2][1]=1;bb[1][2]=a[1];bb[2][2]=a[2];bb[3][2]=a[3]; bb[2][3]=x;bb[3][3]=y;bb[1][4]=y*y;bb[2][4]=x*x; bb[3][4]=2*x*y;bb[4][4]=1; } //矩阵乘法 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(){ while(~scanf("%lld%lld%lld",&mi,&x,&y)){ x=x%MAX;y=y%MAX; ll f[11],num[11]; f[1]=1;f[2]=1;f[3]=1;f[4]=2; num[1]=y*y;num[2]=x*x;num[3]=2*x*y;num[4]=0;num[5]=0; matrix mm; if(mi==1){ cc[1][row-1]=2%MAX; } else if(mi==0) cc[1][row-1]=1%MAX; else{ mm.initmatrix(f,num); mm.matrixmi(mi-1); } printf("%lld\n",cc[1][row-1]); } return 0; }