思路:
由于要求g(g(g(n))) mod 109 + 7
可以先求出g(g(n))
假设g(g(n)) = M
根据测试程序可以知道M是循环的(循环节是222222224)
要求g(g(n))可以先求出g(n)
假设g(n)=N;
根据测试程序可以知道N是循环的(循环节是183120)
//求循环节:
package hpu;
//222222224 183120
public class HDU4291_1 {
private static int mod = 1000000007;
public static void main(String[] args) {
long a = 0;
long b = 1;
long c = 0;
for(int i=2; i<1000000000; i++) {
c = (a + b*3)%mod;
if(c==0 && b==1) {
System.out.println(i);
System.out.println(c);
break;
}
a = b;
b = c;
}
}
}
A Short problem
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1084 Accepted Submission(s): 425
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 <= 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 <= n <= 10 18), You should solve for g(g(g(n))) mod 10 9 + 7 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
package hpu;
import java.util.Scanner;
public class HDU4291 {
private static Long n;
private static int mod = 0;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while(sc.hasNextLong()) {
n = sc.nextLong();
mod = 183120;
n = sovle(mod);
mod = 222222224;
n = sovle(mod);
mod = 1000000007;
n = sovle(mod);
System.out.println(n);
}
}
private static long sovle(int M) {
long[][] result = new long[][]{{1, 0}, {0, 1}};
result = new long[][]{{1, 0}, {0, 1}};
long[][] a = new long[][]{{3, 1}, {1, 0}};
while(n > 0) {
if((n&1) == 1) {
result = matrixMul(result, a, M);
}
a = matrixMul(a, a, M);
n >>= 1;
}
return result[0][1];
}
private static long[][] matrixMul(long[][] a, long[][] b, int M) {
long result[][] = new long[2][2];
for(int i=0; i<2; i++) {
for(int j=0; j<2; j++) {
for(int k=0; k<2; k++) {
result[i][j] = (result[i][j]+a[i][k]*b[k][j])%M;
}
}
}
return result;
}
}