HDU4686 Arc of Dream 矩阵
欢迎访问~原文出处——博客园-zhouzhendong
去博客园看该题解
题目传送门 - HDU4686
题意概括
a0 = A0
ai = ai-1*AX+AY
b0 =
B0
bi = bi-1*BX+BY
求AoD(n)
n=0时答案为0!!!!
题解
具体的矩阵构建思路指导可以参考例题链接。
这里仅提供运算过程。
Ai=Ai-1*AX+AY
Bi=Bi-1*BX+BY
AiBi=(Ai-1*AX+AY)(Bi-1*BX+BY)
=AX*BX*Ai-1*Bi-1+AX*BY*Ai-1+BX*AY*Bi-1+AY*BY
Si AiBi Ai Bi K
Si-1 1 0 0 0 0
Ai-1Bi-1 AX*BX AX*BX 0 0 0
Ai-1 AX*BY AX*BY AX 0 0
Bi-1 BX*AY BX*AY 0 BX 0
K AY*BY AY*BY AY BY 1
初始矩阵:
S0 A0B0 A0 B0 K
A0*B0 A0*B0 A0 B0 1
代码
#include <cstring> #include <algorithm> #include <cstdio> #include <cmath> #include <cstdlib> using namespace std; typedef long long LL; const LL mod=1000000007,m=5; LL n,A0,AX,AY,B0,BX,BY; struct Mat{ LL v[m][m]; Mat (){} Mat (LL x){ (*this).set(x); } void set(LL x){ memset(v,0,sizeof v); if (x==1) for (int i=0;i<m;i++) v[i][i]=1; } Mat operator * (Mat x){ Mat ans(0); for (int i=0;i<m;i++) for (int j=0;j<m;j++) for (int k=0;k<m;k++) ans.v[i][j]=(ans.v[i][j]+v[i][k]*x.v[k][j])%mod; return ans; } void operator *= (Mat x){ (*this)=(*this)*x; } }M,Md; Mat MatPow(Mat x,LL y){ Mat ans(1),now=x; while (y){ if (y&1LL) ans*=now; now*=now; y>>=1; } return ans; } int main(){ while (~scanf("%lld%lld%lld%lld%lld%lld%lld",&n,&A0,&AX,&AY,&B0,&BX,&BY)){ if (!n){ puts("0"); continue; } A0%=mod,AX%=mod,AY%=mod,B0%=mod,BX%=mod,BY%=mod; LL NewArr[m][m]={{1 ,0 ,0 ,0 ,0}, {AX*BX%mod ,AX*BX%mod ,0 ,0 ,0}, {AX*BY%mod ,AX*BY%mod ,AX ,0 ,0}, {BX*AY%mod ,BX*AY%mod ,0 ,BX ,0}, {AY*BY%mod ,AY*BY%mod ,AY ,BY ,1}}; LL NewArr2[m]= {A0*B0%mod ,A0*B0%mod ,A0 ,B0 ,1}; memcpy(Md.v,NewArr,sizeof NewArr); memcpy(M.v[0],NewArr2,sizeof NewArr2); Md=MatPow(Md,n-1); M*=Md; printf("%lld\n",M.v[0][0]); } return 0; }