利用矩阵法求f(n),其中f(n)=3*f(n-1)+f(n-2) f(0)=0,f(1)=1
接着就是求循环节,即可。
求循环节:
#include<iostream> #include<stdio.h> using namespace std; typedef long long LL; const LLMOD = 1000000007LL; int main() { LL f0 = 0, f1 = 1, temp = -1; for (LL i = 1;; i++) { temp = (3 * f1 + f0) % MOD; f0 = f1; f1 = temp; if (f0 == 0 && f1 == 1) { printf("%I64d\n", i); break; } } return 0; } //const LL MOD = 1000000007LL; //222222224 //const LL MOD = 222222224LL; //183120
import java.io.BufferedInputStream; import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner cin = new Scanner(new BufferedInputStream(System.in)); long n = -1; while (cin.hasNext()) { n = cin.nextLong(); System.out.println(cal(cal(cal(n, 183120), 222222224), 1000000007)); } cin.close(); } static long numa[][] = new long[2][2]; static long numb[][] = new long[2][2]; public static void matrix(long[][] a, long[][] b, int mark, long MOD) { long[][] temp = new long[2][2]; temp[0][0] = (a[0][0] * b[0][0] % MOD + a[0][1] * b[1][0] % MOD) % MOD; temp[0][1] = (a[0][0] * b[0][1] % MOD + a[0][1] * b[1][1] % MOD) % MOD; temp[1][0] = (a[1][0] * b[0][0] % MOD + a[1][1] * b[1][0] % MOD) % MOD; temp[1][1] = (a[1][0] * b[0][1] % MOD + a[1][1] * b[1][1] % MOD) % MOD; if (mark == 1) { for (int i = 0; i < 2; i++) { for (int j = 0; j < 2; j++) { numa[i][j] = temp[i][j]; } } } else { for (int i = 0; i < 2; i++) { for (int j = 0; j < 2; j++) { numb[i][j] = temp[i][j]; } } } } public static long cal(long n, long MOD) { numa[0][0] = 1; numa[0][1] = 0; numa[1][0] = 0; numa[1][1] = 1; numb[0][0] = 3; numb[0][1] = 1; numb[1][0] = 1; numb[1][1] = 0; while (n != 0) { if (n % 2 == 1) { matrix(numa, numb, 1, MOD); } matrix(numb, numb, 0, MOD); n >>= 1; } return numa[0][1]; } }
/* * Main.cpp * * Created on: 2012-9-16 * Author: wangzhu */ #include<iostream> #include<stdio.h> #include<math.h> using namespace std; #define LL long long LL numa[2][2], numb[2][2]; void matrix(LL a[2][2], LL b[2][2], int mark, LL MOD) { LL temp[2][2]; temp[0][0] = (a[0][0] * b[0][0] % MOD + a[0][1] * b[1][0] % MOD) % MOD; temp[0][1] = (a[0][0] * b[0][1] % MOD + a[0][1] * b[1][1] % MOD) % MOD; temp[1][0] = (a[1][0] * b[0][0] % MOD + a[1][1] * b[1][0] % MOD) % MOD; temp[1][1] = (a[1][0] * b[0][1] % MOD + a[1][1] * b[1][1] % MOD) % MOD; if (mark) { for (int i = 0; i < 2; i++) { for (int j = 0; j < 2; j++) { numa[i][j] = temp[i][j]; } } } else { for (int i = 0; i < 2; i++) { for (int j = 0; j < 2; j++) { numb[i][j] = temp[i][j]; } } } } LL cal(LL n, LL MOD) { numa[0][0] = 1; numa[0][1] = 0; numa[1][0] = 0; numa[1][1] = 1; numb[0][0] = 3; numb[0][1] = 1; numb[1][0] = 1; numb[1][1] = 0; while (n) { if (n & 1) { matrix(numa, numb, 1, MOD); } matrix(numb, numb, 0, MOD); n >>= 1; } return numa[0][1]; } int main() { #ifndef ONLINE_JUDGE freopen("data.in", "r", stdin); #endif LL n; while (~scanf("%I64d", &n)) { printf("%I64d\n", cal(cal(cal(n, 183120LL), 222222224LL),1000000007LL)); } return 0; }