A Short problem
Time Limit: 1000ms
Memory Limit: 32768KB
This problem will be judged on HDU. Original ID: 429164-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]
Hence they prefer problems short, too. Here is a short one:
Given $n (1 leq n leq 10^{18})$, You should solve for
where
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).
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 ",quickPow(quickPow(quickPow(m,183120),222222224),1000000007)); 62 return 0; 63 }