HDU4686 Arc of Dream —— 矩阵快速幂

题目链接: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?
 

 

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
 

 

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\n", 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\n", ans);
90     }
91 }
View Code

 

posted on 2018-02-07 15:39  h_z_cong  阅读(302)  评论(0编辑  收藏  举报

导航