HDU 4291 A Short problem

A Short problem

Time Limit: 1000ms
Memory Limit: 32768KB
This problem will be judged on HDU. Original ID: 4291
64-bit integer IO format: %I64d      Java class name: Main
 
 According to a research, VIM users tend to have shorter fingers, compared with Emacs users.
  Hence they prefer problems short, too. Here is a short one:
  Given $n (1 \leq n \leq 10^{18})$, You should solve for 
\[g(g(g(n))) mod 10^9 + 7\]

  where
\[g(n) = 3g(n - 1) + g(n - 2)\]

\[g(1) = 1\]

\[g(0) = 0\]

 

Input

  There are several test cases. For each test case there is an integer n in a single line.
  Please process until EOF (End Of File).
 

Output

  For each test case, please print a single line with a integer, the corresponding answer to this case.
 

Sample Input

0
1
2

Sample Output

0
1
42837

Source

 
解题:矩阵快速幂,关键在于如何找到内部循环的的模对象
 
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long LL;
 4 const int maxn = 3;
 5 LL mod = 1000000007;
 6 const int n = 2;
 7 struct Matrix {
 8     LL m[maxn][maxn];
 9     void init() {
10         memset(m,0,sizeof m);
11     }
12     Matrix() {
13         init();
14     }
15     Matrix operator*(const Matrix &rhs) const {
16         Matrix ret;
17         for(int k = 0; k < n; ++k) {
18             for(int i = 0; i < n; ++i)
19                 for(int j = 0; j < n; ++j)
20                     ret.m[i][j] = (ret.m[i][j] + m[i][k]*rhs.m[k][j]%mod)%mod;
21 
22         }
23         return ret;
24     }
25     void set_a() {
26         init();
27         m[0][0] = 0;
28         m[0][1] = 1;
29     }
30     void set_b() {
31         init();
32         m[0][0] = 0;
33         m[0][1] = m[1][0] = 1;
34         m[1][1] = 3;
35     }
36     void print() {
37         for(int i = 0; i < n; ++i) {
38             for(int j = 0; j < n; ++j)
39                 cout<<m[i][j]<<" ";
40             cout<<endl;
41         }
42     }
43 };
44 Matrix a,b;
45 LL quickPow(LL index,LL md) {
46     a.set_a();
47     b.set_b();
48     mod = md;
49     while(index) {
50         if(index&1) {
51             a = a*b;
52         }
53         index >>= 1;
54         b = b*b;
55     }
56     return a.m[0][0];
57 }
58 int main() {
59     LL m;
60     while(~scanf("%I64d",&m))
61         printf("%I64d\n",quickPow(quickPow(quickPow(m,183120),222222224),1000000007));
62     return 0;
63 }
View Code

 

posted @ 2015-09-17 14:10  狂徒归来  阅读(174)  评论(0编辑  收藏  举报