HDU 4686 Arc of Dream(矩阵快速幂)

大意:已知 a0 = A0
ai = ai-1*AX+AY
b0 = B0
bi = bi-1*BX+BY
这里写图片描述
What is the value of AoD(N) modulo 1,000,000,007?

思路:已知an,bn是一个递推式,AoD(n)也是一个递推式,所以试想用一个快速幂解决。那么就应该把a0,b0,ax,ay,bx,by代进去构成一个式子。那么就可以构造矩阵了。因为an,bn,AoD,都需要求所以根据需要构成一个7*7的矩阵。
HDU 4686 Arc of Dream(矩阵快速幂)_第1张图片

那么什么又是最后的答案呢?肯定是构造矩阵连乘后的结果乘以初始值。
(PS:n可能为0,优化一下)

#include<map>
#include<cmath>
#include<queue>
#include<cmath>
#include<string>
#include<cstdio>
#include<stack>
#include<iostream>
#include<cstring>
#include<algorithm>
#define inf 0x3f3f3f3f
#define eps 1e-8
#define ls l,mid,rt<<1
#define rs mid+1,rt,rt<<1|1
#define LL __int64
using namespace std;
__int64 mod = 1000000007,MOD = 1000000007,N=7;
__int64 a,ax,ay,b,bx,by,n;

struct node{
    __int64 r[10][10];
}q;

node matrix_pow(node a,node b){
    __int64 i,j,k;
    node t;
    memset(t.r,0,sizeof(t.r));
    for(k = 0;k < 7;++ k){
        for(i = 0 ;i < 7;++ i){
            for(j = 0;j < 7;++ j){
                t.r[i][j] = (t.r[i][j]+ (a.r[i][k]*b.r[k][j]))%mod;
            }
        }
    }
    return t;
}

node so(node q,__int64 m){
    __int64 i,j,k;
    node tmp;
    memset(tmp.r,0,sizeof(tmp.r));
    for(i = 0;i < N;++ i )
            tmp.r[i][i] = 1;
    while(m){
        if(m&1)
            tmp = matrix_pow(tmp,q);
        q = matrix_pow(q,q);
        m = m >> 1;
    }
    __int64 sum = 0;
    sum += tmp.r[N-1][0]*(a*b%MOD)%MOD;
    sum %= MOD;
    sum += tmp.r[N-1][1]*a%MOD;
    sum %= MOD;
    sum += tmp.r[N-1][2]*b%MOD;
    sum %= MOD;
    sum += tmp.r[N-1][3]*(ay*by%MOD)%MOD;
    sum %= MOD;
    sum += tmp.r[N-1][4]*ay%MOD;
    sum %= MOD;
    sum += tmp.r[N-1][5]*by%MOD;
    sum %= MOD;
    printf("%I64d\n",sum);
}

int main(){
    __int64 m,k,i,j;
    while(~scanf("%I64d",&n)){
        scanf("%I64d%I64d%I64d%I64d%I64d%I64d",&a,&ax,&ay,&b,&bx,&by);
        memset(q.r,0,sizeof(q.r));
        q.r[0][0] = ax*bx%mod;  q.r[0][2] = bx*ay%mod;
        q.r[0][1] = ax*by%mod;  q.r[0][3] = 1;
        q.r[1][1] = ax%mod; q.r[1][4] = 1;
        q.r[2][2] = bx%mod; q.r[2][5] = 1;

        q.r[3][3] = 1;q.r[4][4] = 1;
        q.r[5][5] = 1;
        q.r[6][6] = q.r[6][0] = 1;
        q = so(q,n);
    }
    return 0;
}

你可能感兴趣的:(矩阵快速幂)