题目链接:https://vjudge.net/problem/HDU-4686
Arc of Dream
Time Limit: 2000/2000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others)
Total Submission(s): 5506 Accepted Submission(s): 1713
Problem Description
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?
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.
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
Author
Zejun Wu (watashi)
Source
题解:
学习之处:
矩阵所要维护的,要么为变量,要么为常数1,而不是变量再乘上一个系数,或者是一个非1的常数。因为:假如变量需要乘上一个系数,那么可以在n*n矩阵中乘上。同样,如果变量需要加上一个常数,那么在对应1的位置,填上这个常数即可。
代码如下:
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <vector> 6 #include <cmath> 7 #include <queue> 8 #include <stack> 9 #include <map> 10 #include <string> 11 #include <set> 12 using namespace std; 13 typedef long long LL; 14 const int INF = 2e9; 15 const LL LNF = 9e18; 16 const int MOD = 1e9+7; 17 const int MAXN = 1e6+100; 18 19 const int Size = 5; 20 struct MA 21 { 22 LL mat[Size][Size]; 23 void init() 24 { 25 for(int i = 0; i<Size; i++) 26 for(int j = 0; j<Size; j++) 27 mat[i][j] = (i==j); 28 } 29 }; 30 31 MA mul(MA x, MA y) 32 { 33 MA ret; 34 memset(ret.mat, 0, sizeof(ret.mat)); 35 for(int i = 0; i<Size; i++) 36 for(int j = 0; j<Size; j++) 37 for(int k = 0; k<Size; k++) 38 ret.mat[i][j] += 1LL*x.mat[i][k]*y.mat[k][j]%MOD, ret.mat[i][j] %= MOD; 39 return ret; 40 } 41 42 MA qpow(MA x, LL y) 43 { 44 MA s; 45 s.init(); 46 while(y) 47 { 48 if(y&1) s = mul(s, x); 49 x = mul(x, x); 50 y >>= 1; 51 } 52 return s; 53 } 54 55 int main() 56 { 57 LL n, a0, ax, ay, b0, bx, by; 58 while(scanf("%lld",&n)!=EOF) 59 { 60 scanf("%lld%lld%lld", &a0,&ax,&ay); 61 scanf("%lld%lld%lld", &b0,&bx,&by); 62 a0 %= MOD; ax %= MOD; ay %= MOD; 63 b0 %= MOD; bx %= MOD; by %= MOD; 64 65 if(n==0) 66 { 67 printf("%lld ", 0LL); 68 continue; 69 } 70 71 MA s; 72 memset(s.mat, 0, sizeof(s.mat)); 73 s.mat[0][0] = 1; 74 s.mat[0][1] = s.mat[1][1] = 1LL*ax*bx%MOD; 75 s.mat[0][2] = s.mat[1][2] = 1LL*ax*by%MOD; 76 s.mat[0][3] = s.mat[1][3] = 1LL*ay*bx%MOD; 77 s.mat[0][4] = s.mat[1][4] = 1LL*ay*by%MOD; 78 s.mat[2][2] = ax; s.mat[2][4] = ay; 79 s.mat[3][3] = bx; s.mat[3][4] = by; 80 s.mat[4][4] = 1; 81 82 LL f0, s0; 83 s0 = f0 = 1LL*a0*b0%MOD; 84 s = qpow(s, n-1); 85 LL ans = 0; 86 ans += (1LL*s0*s.mat[0][0]%MOD+1LL*f0*s.mat[0][1]%MOD)%MOD, ans %= MOD; 87 ans += (1LL*a0*s.mat[0][2]%MOD+1LL*b0*s.mat[0][3]%MOD)%MOD, ans %= MOD; 88 ans += 1LL*s.mat[0][4]%MOD, ans %= MOD; 89 printf("%lld ", ans); 90 } 91 }