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

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

题目链接http://acm.hdu.edu.cn/showproblem.php?pid=4686

Description

An Arc of Dream is a curve defined by following function:
http://acm.hdu.edu.cn/data/images/C463-1001-1.jpg
where
a0 = A0
ai = ai-1AX+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

题意:

如公式

题解:

这道题目可以构造矩阵,首先我们知道AoD(n) 可以由AoD(n-1)+a[n-1]*b[n-1]求得。这样我们将这些因素构成矩阵即可使用矩阵快速幂优化。**注意n==0的时候输出0. **

代码:

#include <bits/stdc++.h>
using namespace std;
const long long mod = 1000000007;
long long ans[5];
long long s[5][5];
long long tans[5];
long long ts[5][5];
long long ret[5][5];
long long cal[5][5];
long long n,A0,B0,AX,AY,BX,BY;
void mul(long long a[][5],long long b[][5],long long c[][5])
{
    for (int i = 0; i < 5; i++){
        for (int j = 0; j < 5; j++){
            c[i][j] = 0;
            for (int k = 0; k < 5; k++){
                c[i][j] = (c[i][j] + a[i][k]*b[k][j]%mod)%mod;
            }     
        }
    }
}
void init()
{
    ans[0] = A0; ans[1] = B0; ans[2] = A0*B0%mod; ans[3] = ans[2]; ans[4] = 1;
    s[0][0] = AX;s[0][1] = s[0][2] = s[0][3] = 0; s[0][4] = AY;
    s[1][0] = 0;s[1][1] = BX;s[1][2] = s[1][3] = 0;s[1][4] = BY;
    s[2][0] = AX*BY%mod; s[2][1] = AY*BX%mod; s[2][2] = AX*BX%mod; s[2][3] = 0;s[2][4] = AY*BY%mod;
    s[3][0] = AX*BY%mod; s[3][1] = AY*BX%mod; s[3][2] = AX*BX%mod; s[3][3] = 1;s[3][4] = AY*BY%mod;
    s[4][0] = s[4][1] = s[4][2] = s[4][3] = 0;s[4][4] = 1;
}
void cop(long long a[][5],long long b[][5])
{
    for (int i = 0;i < 5; i++){
        for (int j = 0; j < 5; j++)
            a[i][j] = b[i][j];    
    }    
}
void solve()
{
    if (n == 0){
        printf("0\n");
        return ;    
    }
    n--;     
    cop(cal,s);memset(ret,0,sizeof ret);for (int i = 0; i < 5; i++) ret[i][i] = 1;

    while (n){
        if (n%2){
            mul(ret,cal,ts);
            cop(ret,ts);    
        }
        mul(cal,cal,ts);
        cop(cal,ts);
        n /= 2;
    }
    long long rt = 0;
    for (int i = 0; i < 5; i++){
        rt = (rt + ans[i]*ret[3][i]%mod)%mod;    
    }
    printf("%lld\n",rt);
}
int main()
{
    while (~scanf("%lld %lld %lld %lld %lld %lld %lld",&n,&A0,&AX,&AY,&B0,&BX,&BY)){
        init();
        solve();
    }
    return 0;
}
posted @ 2016-10-01 01:04  Thecoollight  阅读(187)  评论(0编辑  收藏  举报