其中a0 = A0
ai = ai-1*AX+AY
b0 = B0
bi = bi-1*BX+BY
最后的结果mod 1,000,000,007
n<=10^18.
ai*bI=Ax*Bx*ai-1*bi-1+Ax*By*ai-1+AyBxbi-1+AyBy
递推式可以构造由矩阵快速幂快速求取。
我理解的递推式构造矩阵的形式可以先这样想(说错了板砖轻拍):
A*[每个递推式的递推项 ]=[每个递推项前进一项]
【f(n-1),a(n-1),b(n-1),1,s(n-2)】*A=【f(n),a(n),b(n),1,s(n-1)】
A那么由此构造A:
| axbx 0 0 0 1 || axby ax 0 0 0 |
| aybx 0 bx 0 0 |
| ayay ay by 1 0 |
| 0 0 0 0 1 |
然后 【f(1), a(1) ,b(1), 1, s(0)】*A^(n-1) = 【f(n), a(n), b(n), 1, s(n-1)】
矩阵快速幂求得A^(n-1) 再处理 s(n)=s(n-1)+f(n);
我的代码的矩阵式A*[]=[]形式的。呵呵。A矩阵是我写的矩阵的逆置矩阵。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <vector>
#define L 5
#define MOD 1000000007
using namespace std;
typedef long long int llint;
typedef vector<llint> vec;
typedef vector<vec> mat;
mat mul(mat a,mat b)
{//矩阵乘法
mat c(L,vec(L));
for(int i=0;i<L;++i)
for(int j=0;j<L;++j)
{
c[i][j]=0;
for(int k=0;k<L;++k)
{
c[i][j]+=a[i][k]*b[k][j];
c[i][j]%=MOD;
}
}
return c;
}
mat quickpow(mat p,llint n)
{
mat res(L,vec(L));
//单位矩阵
for(int i=0;i<L;++i)
for(int j=0;j<L;++j)
if(i==j)
res[i][j]=1;
else res[i][j]=0;
while(n>0)
{
if(n&1)
res=mul(p,res);
n=n>>1;
p=mul(p,p);
}
return res;
}
int main()
{
llint n;
llint a0,ax,ay;
llint b0,bx,by;
while(~scanf("%lld",&n))
{
scanf("%lld%lld%lld",&a0,&ax,&ay);
scanf("%lld%lld%lld",&b0,&bx,&by);
if(n==0)
printf("%lld\n",0);
else if(n==1)
printf("%lld\n", (a0*b0)%MOD);
else {
mat p(L,vec(L));
for(int i=0;i<L;++i)
for(int j=0;j<L;++j)
p[i][j]=0;
//初始A数组
p[0][0]=(ax*bx)%MOD,p[0][1]=(ax*by)%MOD,
p[0][2]=(ay*bx)%MOD,p[0][3]=(ay*by)%MOD;
p[1][1]=ax%MOD,p[1][3]=ay%MOD;
p[2][2]=bx%MOD,p[2][3]=by%MOD;
p[3][3]=1;
p[4][0]=1,p[4][4]=1;
mat f=quickpow(p,n-1);
//f(n)
llint f0=(a0*b0)%MOD;
llint fn=0,fs=0;
fn=(fn+f[0][0]*f0)%MOD;
fn=(fn+f[0][1]*a0)%MOD;
fn=(fn+f[0][2]*b0)%MOD;
fn=(fn+f[0][3])%MOD;
//s(n-1)
fs=(fs+f[4][0]*f0)%MOD;
fs=(fs+f[4][1]*a0)%MOD;
fs=(fs+f[4][2]*b0)%MOD;
fs=(fs+f[4][3])%MOD;
printf("%lld\n",(fs+fn)%MOD);
}
}
return 0;
}