Arc of Dream HDU - 4686

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
*/

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325479674&siteId=291194637
arc