HDU Arc of Dream

An Arc of Dream is a curve defined by following function:


where
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?


Input
There are multiple test cases. Process to the End of File.
Each test case contains 7 nonnegative integers as follows:
N
A0 AX AY
B0 BX BY
N is no more than 1018, and all the other integers are no more than 2×109.


Output
For each test case, output AoD(N) modulo 1,000,000,007.


Sample Input
1
1 2 3
4 5 6
2
1 2 3
4 5 6
3
1 2 3
4 5 6


Sample Output
4
134

1902

矩阵快速幂

根据ai*bi = ai-1 * bi-1 * AX*BX + ai-1 * AX*BY + bi-1 * BX*AY + AY*BY构造一个5x5的矩阵。

|AXBX   AXBY   AYBX    AYBY    0   |    | ai-1*bi-1  |    | ai*bi  |

|   0        AX     0         AY      0  |     |   ai-1       |                | ai       |

| 0         0          BX        BY     0   | *  |   bi-1  | =     |   bi  |

 | 0         0           0          1        0   |          |   1     |    |    1  |

|AXBX   AXBY   AYBX    AYBY    1  | |   AoD(n-1)    |       |  AoD(n)    |

#include<iostream>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<ctime>
#include<string>
#include<stack>
#include<deque>
#include<queue>
#include<list>
#include<set>
#include<map>
#include<cstdio>
#define mes(x) memset(x, 0, sizeof(x))
#define Pii pair<int, int>
#define Pll pair<ll, ll>
#define INF 1e9+7
typedef long long ll;
using namespace std;
const int MAX = 101;
#define MOD 1000000007
#define fir first
#define sec second
#define fin freopen("/home/ostreambaba/文档/input.txt", "r", stdin)
#define fout freopen("/home/ostreambaba/文档/output.txt", "w", stdout)
#define time
#define test
struct Matrix
{
    ll mat[5][5];
    void inti(){
        mes(mat);
        for(int i = 0; i < 5; ++i){
            mat[i][i] = 1;
        }
    }
    void output(){
        for(int i = 0; i < 5; ++i){
            for(int j = 0;  j < 5; ++j){
                cout << mat[i][j] << " ";
            }
            cout << endl;
        }
    }
    Matrix operator*(const Matrix &b) const
    {
        Matrix temp;
        mes(temp.mat);
        for(int i = 0; i < 5; ++i)
            for(int j = 0; j < 5; ++j)
                for(int k = 0; k < 5; ++k)
                    temp.mat[i][j] = (temp.mat[i][j]+mat[i][k]*b.mat[k][j]%MOD)%MOD;
        return temp;
    }
};

Matrix matrix_fast_mod(Matrix &base, ll n)
{
    Matrix ans;
    ans.inti();
    while(n)
    {
        if(n & 1)
           ans = ans*base;
        base = base*base;
        n >>= 1;
    }
    return ans;
}

int main()
{
    //fin;
    ll n, A0, AX, AY, B0, BX, BY;
    Matrix base;
    while(~scanf("%lld", &n))
    {
        scanf("%lld%lld%lld", &A0, &AX, &AY);
        scanf("%lld%lld%lld", &B0, &BX, &BY);
        if(0 == n){
            cout << "0" << endl;
        }
        else
        {
            mes(base.mat);
            base.mat[0][0] = AX*BX%MOD;
            base.mat[0][1] = AX*BY%MOD;
            base.mat[0][2] = AY*BX%MOD;
            base.mat[0][3] = AY*BY%MOD;
            base.mat[1][1] = AX%MOD;
            base.mat[1][3] = AY%MOD;
            base.mat[2][2] = BX%MOD;
            base.mat[2][3] = BY%MOD;
            base.mat[3][3] = 1;
            base.mat[4][0] = AX*BX%MOD;
            base.mat[4][1] = AX*BY%MOD;
            base.mat[4][2] = AY*BX%MOD;
            base.mat[4][3] = AY*BY%MOD;
            base.mat[4][4] = 1;
            base = matrix_fast_mod(base, n-1);
            ll t1 = A0*B0%MOD;
            ll t2 = A0%MOD;
            ll t3 = B0%MOD;
            ll t4 = (base.mat[4][0]*t1%MOD + base.mat[4][1]*t2%MOD + base.mat[4][2]*t3%MOD + base.mat[4][3] + base.mat[4][4]*t1%MOD) % MOD;
            cout << t4 << endl;
        }
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值