hdu 4686 (矩阵快速幂)
题意:
a 0 = A0
a i = a i-1*AX+AY
b 0 = B0
b i = b i-1*BX+BY
求AoD(N) mod 1000000007
思路:
做这道题时思路没有打开,一直纠结于如何把公式加一起.....
正确是做法是把AoD这个和加到你的构造矩阵里来递推计算
aibi=(Ax*Bx)*ai-1*bi-1 + (Ax*By)*ai-1 + (Ay*Bx)*bi-1 + Ay*By
代码:
#include <cstdio> #include <cstring> #include <iostream> using namespace std; typedef long long ll; const int N=5,M=5,P=5; const ll MOD=1000000007; struct Matrix { ll m[N][N]; }; Matrix A; Matrix I={1,0,0,0,0, 0,1,0,0,0, 0,0,1,0,0, 0,0,0,1,0, 0,0,0,0,1}; Matrix multi(Matrix a,Matrix b) { Matrix ans; for(int i=0;i<N;i++) { for(int j=0;j<M;j++) { ans.m[i][j]=0; for(int k=0;k<P;k++) { ans.m[i][j]+=a.m[i][k]*b.m[k][j]%MOD; } ans.m[i][j]%=MOD; } } return ans; } Matrix power(Matrix a,ll k) { Matrix ans=I,p=a; while(k) { if(k&1) { ans=multi(ans,p); } k>>=1; p=multi(p,p); } return ans; } int main(int argc, char const *argv[]) { ll n; ll A0,Ax,Ay,B0,Bx,By; while(cin>>n) { scanf("%lld %lld %lld",&A0,&Ax,&Ay); scanf("%lld %lld %lld",&B0,&Bx,&By); if(n==0) { cout<<"0"<<endl; continue; } A0%=MOD; Ax%=MOD; Ay%=MOD; B0%=MOD; Bx%=MOD; By%=MOD; A.m[0][0]=1; A.m[0][1]=(Ax*Bx)%MOD; A.m[0][2]=(Ax*By)%MOD; A.m[0][3]=(Ay*Bx)%MOD; A.m[0][4]=(Ay*By)%MOD; A.m[1][0]=0; A.m[1][1]=(Ax*Bx)%MOD; A.m[1][2]=(Ax*By)%MOD; A.m[1][3]=(Ay*Bx)%MOD; A.m[1][4]=(Ay*By)%MOD; A.m[2][0]=0; A.m[2][1]=0; A.m[2][2]=(Ax)%MOD; A.m[2][3]=0; A.m[2][4]=(Ay)%MOD; A.m[3][0]=0; A.m[3][1]=0; A.m[3][2]=0; A.m[3][3]=(Bx)%MOD; A.m[3][4]=(By)%MOD; A.m[4][0]=0; A.m[4][1]=0; A.m[4][2]=0; A.m[4][3]=0; A.m[4][4]=1; Matrix ans=power(A,(n-1)); ll num=0; ll a=(A0*B0)%MOD; ll b=(A0*B0)%MOD; ll c=A0%MOD; ll d=B0%MOD; ll e=1; num=(num+(ans.m[0][0]*a)%MOD)%MOD; num=(num+(ans.m[0][1]*b)%MOD)%MOD; num=(num+(ans.m[0][2]*c)%MOD)%MOD; num=(num+(ans.m[0][3]*d)%MOD)%MOD; num=(num+(ans.m[0][4]*e)%MOD)%MOD; printf("%lld\n",num); } return 0; }