http://acm.hdu.edu.cn/showproblem.php?pid=4686
Multiply ai and bi to get the recursive formula of aibi. Here, to find the sum of the first n items is actually to find the sum of the first n items of the recursive matrix. If you know the sum of the first n/2 items, you can get it by multiplying a certain matrix. The last n/2 items and a half can be
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
const ll mod=1e9+7;
const int maxn=5;
ll mat[maxn][maxn],ans[maxn][maxn],pre[maxn][maxn],tmp[maxn][maxn];
ll n,a0,ax,ay,b0,bx,by;
void show(ll gou[][maxn])
{
int i,j;
for(i=0;i<4;i++){
for(j=0;j<4;j++){
printf("%lld ",gou[i][j]);
}
printf("\n");
}
}
void init()
{
int i;
mat[0][0]=(ax*bx)%mod,mat[0][1]=0,mat[0][2]=0,mat[0][3]=0;
mat[1][0]=(ax*by)%mod,mat[1][1]=ax%mod,mat[1][2]=0,mat[1][3]=0;
mat[2][0]=(ay*bx)%mod,mat[2][1]=0,mat[2][2]=bx%mod,mat[2][3]=0;
mat[3][0]=(ay*by)%mod,mat[3][1]=ay%mod,mat[3][2]=by%mod,mat[3][3]=1;
memset(ans,0,sizeof(ans));
for(i=0;i<4;i++){
ans[i][i]=1;
}
//show(mat);
}
void getmul(ll a[][maxn],ll b[][maxn],ll c[][maxn])
{
ll t[maxn][maxn];
int i,j,k;
for(i=0;i<4;i++){
for(j=0;j<4;j++){
t[i][j]=0;
for(k=0;k<4;k++){
t[i][j]=(t[i][j]+(a[i][k]*b[k][j])%mod)%mod;
}
}
}
memcpy(c,t,sizeof(t));
}
void getadd(ll a[][maxn],ll b[][maxn],ll c[][maxn])
{
ll t[maxn][maxn];
int i,j;
for(i=0;i<4;i++){
for(j=0;j<4;j++){
t[i][j]=(a[i][j]+b[i][j])%mod;
}
}
memcpy(c,t,sizeof(t));
}
void quickpow(ll n)
{
int i;
memset(pre,0,sizeof(pre));
for(i=0;i<4;i++) pre[i][i]=1;
memcpy(tmp,mat,sizeof(mat));
while(n>0){
if(n%2) getmul(pre,tmp,pre);
getmul(tmp,tmp,tmp),n/=2;
}
}
void solve(ll n)
{
ll mid[maxn][maxn],rgt[maxn][maxn];
//printf("***%lld***\n",n);
if(n==1) return;
if(n%2){
solve(n/2);
quickpow(n/2);
memcpy(mid,pre,sizeof(pre));
quickpow(n/2+1);
getmul(pre,ans,rgt);
getadd(ans,mid,ans);
getadd(ans,rgt,ans);
}
else{
solve(n/2);
quickpow(n/2);
getmul(pre,ans,rgt);
getadd(ans,rgt,ans);
}
}
int main()
{
ll syt;
while(scanf("%lld%lld%lld%lld%lld%lld%lld",&n,&a0,&ax,&ay,&b0,&bx,&by)!=EOF){
if(n==0){
printf("0\n");
continue;
}
init();
solve(n);
syt=(a0*b0%mod*ans[0][0]%mod+a0*ans[1][0]%mod+b0*ans[2][0]%mod+ans[3][0])%mod;
printf("%lld\n",syt);
}
return 0;
}
/*
2
1 2 3
4 5 6
*/