A Short problem
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission (s): 1110 Accepted Submission (s): 436
Problem Description
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 <=n <= 1018), You shoshould solve
G (n) mod 109 + 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
Analysis: Assume that g (n) = g (x), x may be very large, but because mod 10 ^ 9 + 7, we can find the cyclic section of x.
After finding the circular section of x, assume that g (n) = g (x) = g (y), that is, x = g (y ), y may be very large, but the circular section of y can be obtained from the circular section of x.
Therefore, the final result can be obtained as long as the matrix is quickly idempotent.
# Include <iostream> # include <cstdio> # include <cstdlib> # include <cstring> # include <string> # include <queue> # include <algorithm> # include <map> # include <iomanip> # define INF 99999999 using namespace std; const int mod1 = 1000000007; // The cyclic section of the result. const int mod2 = 222222224; // The cyclic section of the 1st layer, assuming g (n ))) = g (x), that is, mod2 is the circular section const int mod3 = 183120 of x; // The circular section of Layer 2 assumes g (n ))) = g (y), that is, mod3 is the progressive section of y _ int64 array [2] [2], sum [2] [2]; void M AtrixMult (_ int64 a [2] [2] ,__ int64 B [2] [2], int mod) {_ int64 c [2] [2] = {0}; for (int I = 0; I <2; ++ I) {for (int j = 0; j <2; ++ j) {for (int k = 0; k <2; ++ k) {c [I] [j] + = a [I] [k] * B [k] [j] ;}} for (int I = 0; I <2; ++ I) {for (int j = 0; j <2; ++ j) a [I] [j] = c [I] [j] % mod ;}} _ int64 Matrix (_ int64 k, int mod) {array [0] [0] = 3, array [1] [1] = 0; array [0] [1] = array [1] [0] = 1; sum [0] [0] = sum [1] [1] = 1; sum [0] [1] = sum [1] [0] = 0; while (k) {if (k & 1) MatrixMu Lt (sum, array, mod); MatrixMult (array, array, mod); k >>=1;} return sum [0] [0];} int main () {/* _ int64 a = 0, B = 1; for (int I = 2; ++ I) {// calculate the cyclic section a = (B * 3 + a) % mod2; a = a ^ B; B = a ^ B; a = a ^ B; if (a = 0 & B = 1) {cout <I-1 <endl; break;} // I-1 = 222222224} */_ int64 n; while (scanf ("% I64d", & n )! = EOF) {if (n> = 2) n = Matrix (n-1, mod3); if (n> = 2) n = Matrix (n-1, mod2 ); if (n> = 2) n = Matrix (n-1, mod1); printf ("% I64d \ n", n);} return 0 ;} # include <iostream> # include <cstdio> # include <cstdlib> # include <cstring> # include <string> # include <queue> # include <algorithm> # include <map> # include <iomanip> # define INF 99999999 using namespace std; const int mod1 = 1000000007; // The cyclic section of the result. const int mod2 = 222222224; // The cyclic section of the 1st layer, assuming g (n ))) = g (x ), That is, mod2 is the cycle section const int mod3 = 183120 of x; // The cycle section of the 2nd layer assumes g (n ))) = g (y), that is, mod3 is the progressive section of y _ int64 array [2] [2], sum [2] [2]; void MatrixMult (_ int64 a [2] [2] ,__ int64 B [2] [2], int mod) {__ int64 c [2] [2] = {0}; for (int I = 0; I <2; ++ I) {for (int j = 0; j <2; ++ j) {for (int k = 0; k <2; ++ k) {c [I] [j] + = a [I] [k] * B [k] [j] ;}} for (int I = 0; I <2; ++ I) {for (int j = 0; j <2; ++ j) a [I] [j] = c [I] [j] % mod ;}} __int64 Matrix (_ int64 k, int mod) {array [0] [0] = 3, array [1] [1] = 0; Array [0] [1] = array [1] [0] = 1; sum [0] [0] = sum [1] [1] = 1; sum [0] [1] = sum [1] [0] = 0; while (k) {if (k & 1) MatrixMult (sum, array, mod ); matrixMult (array, array, mod); k >>=1;} return sum [0] [0];} int main () {/* _ int64 a = 0, B = 1; for (int I = 2; ++ I) {// calculates the cyclic section a = (B * 3 + a) % mod2; a = a ^ B; B = a ^ B; a = a ^ B; if (a = 0 & B = 1) {cout <I-1 <endl; break ;} // I-1 = 222222224} */_ int64 n; while (scanf ("% I64d", & n )! = EOF) {if (n> = 2) n = Matrix (n-1, mod3); if (n> = 2) n = Matrix (n-1, mod2 ); if (n> = 2) n = Matrix (n-1, mod1); printf ("% I64d \ n", n);} return 0 ;}