欢迎访问~原文出处——博客园-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;
}