HDU 6470 Count 【矩阵快速幂】(广东工业大学第十四届程序设计竞赛 )

题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6470

Count

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 301    Accepted Submission(s): 127


Problem Description
Farmer John有n头奶牛.
某天奶牛想要数一数有多少头奶牛,以一种特殊的方式:
第一头奶牛为1号,第二头奶牛为2号,第三头奶牛之后,假如当前奶牛是第n头,那么他的编号就是2倍的第n-2头奶牛的编号加上第n-1头奶牛的编号再加上自己当前的n的三次方为自己的编号.
现在Farmer John想知道,第n头奶牛的编号是多少,估计答案会很大,你只要输出答案对于123456789取模.
 

 

Input
第一行输入一个T,表示有T组样例
接下来T行,每行有一个正整数n,表示有n头奶牛 (n>=3)
其中,T=10^4,n<=10^18
 

 

Output
共T行,每行一个正整数表示所求的答案
 

 

Sample Input
5
3
6
9
12
15
 

 

Sample Output
31
700
7486
64651
527023
 

 

Source

 

 

解题思路:

很裸的一道矩阵快速幂的题,递推式都给出来了。

问题在于如何构造转移矩阵?也就是如何搞定 n 的3次方?

 

 

 

最终的转移矩阵:

 

AC code:

 1 #include <bits/stdc++.h>
 2 #define INF 0x3f3f3f3f
 3 #define LL long long
 4 using namespace std;
 5 const int MAXN = 7;
 6 const LL MOD = 123456789;
 7 template<typename T, int N = 1>
 8 struct Matrix
 9 {
10     Matrix(int f = 0):n(sizeof(data[0])/sizeof(data[0][0])){
11         for(int i = 0; i < n; i++)
12             for(int j = 0; j < n; j++)
13                 data[i][j] = 0;
14         if(f)
15             for(int i = 0; i < n; i++) data[i][i] = T(1);
16     }
17 
18     Matrix operator * (const Matrix other) const{
19         Matrix<T, N> ret;
20         for(int i = 0; i < n; i++)
21             for(int j = 0; j < n; j++)
22                 for(int k = 0; k < n; k++)
23                 ret.data[i][j] = (ret.data[i][j] + data[i][k] * other.data[k][j]%MOD)%MOD;
24         return ret;
25     }
26 
27     Matrix operator + (const Matrix other) const{
28         Matrix<T, N> ret;
29         for(int i = 0; i < n; i++)
30             for(int j = 0; j < n; j++)
31             ret.data[i][j] = (data[i][j] + other[i][j])%MOD;
32         return ret;
33     }
34 
35     Matrix operator % (const LL MOD){
36         return *this;
37     }
38 
39     T data[N][N];
40     int n;
41 
42 };
43 
44 template<typename T>
45 T mul(T a, LL n, LL mod)
46 {
47     T ret(1);
48     for(; n ; n >>= 1){
49         ret = ret*(n&1 ? a:T(1)) %mod;
50         a = a*a%mod;
51     }
52     return ret;
53 }
54 
55 const LL modulu[MAXN][MAXN] = {
56     {1, 2, 1, 0, 0, 0},
57     {1, 0, 0, 0, 0, 0},
58     {0, 0, 1, 3, 3, 1},
59     {0, 0, 0, 1, 2, 1},
60     {0, 0, 0, 0, 1, 1},
61     {0, 0, 0, 0, 0, 1}
62 };
63 
64 int main()
65 {
66     std::ios::sync_with_stdio(false);
67     int T;
68     cin >> T;
69     for(LL n; T--; ){
70         cin >> n;
71         if(n <= 2){
72             cout << n << endl;
73             continue;
74         }
75         Matrix<LL, MAXN> a;
76         memcpy(a.data, modulu, sizeof(modulu));
77         a = mul(a, n-2, MOD);
78         cout << (a.data[0][0]*2 + a.data[0][1]*1 + a.data[0][2]*27 + a.data[0][3]*9 + a.data[0][4]*3 + a.data[0][5]*1)%MOD << endl;
79     }
80     return 0;
81 }
View Code

 

posted @ 2019-03-17 17:10  莜莫  阅读(431)  评论(0编辑  收藏  举报