矩阵快速幂。最外层的取模是1e9+7,第二层的取模 L1 = (1e9+7的循环节),第三层的取模是 L2 = (L1的循环节)
暴力找出L2, L1, 然后矩阵快速幂即可。。。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <iostream> #include <cstdio> #include <cmath> #include <vector> #include <cstring> #include <algorithm> #include <string> #include <set> #include <functional> #include <numeric> #include <sstream> #include <stack> #define CL(arr, val) memset(arr, val, sizeof(arr)) #define REP(i, n) for((i) = 0; (i) < (n); ++(i)) #define FOR(i, l, h) for((i) = (l); (i) <= (h); ++(i)) #define FORD(i, h, l) for((i) = (h); (i) >= (l); --(i)) #define L(x) (x) << 1 #define R(x) (x) << 1 | 1 #define MID(l, r) (l + r) >> 1 #define Min(x, y) x < y ? x : y #define Max(x, y) x < y ? y : x #define E(x) (1 << (x)) #define iabs(x) (x) < 0 ? -(x) : (x) #define OUT(x) printf("%I64d\n", x) #define lowbit(x) (x)&(-x) #define Read() freopen("data.in", "r", stdin) #define Write() freopen("data.out", "w", stdout); const double eps = 1e-8; typedef long long LL; const int inf = ~0u>>2; using namespace std; int mod; int l2 = 183120; int l1 = 222222224; struct Mat { LL mat[3][3]; void init() { mat[0][0] = 3; mat[0][1] = 1; mat[1][0] = 1; mat[1][1] = 0; } }a; Mat operator * (Mat a, Mat b) { Mat c; CL(c.mat, 0); int i, j, k; REP(k, 2) { REP(i, 2) { if(a.mat[i][k] <= 0) continue; REP(j, 2) { if(b.mat[k][j] <= 0) continue; c.mat[i][j] = (c.mat[i][j] + (a.mat[i][k] * b.mat[k][j])%mod)%mod; } } } return c; } Mat operator ^ (Mat a, LL k) { Mat c; int i, j; REP(i, 2) REP(j, 2) c.mat[i][j] = (i == j); for(; k; k >>= 1) { if(k&1) c = c*a; a = a*a; } return c; } LL solve(LL n, LL m) { a.init(); mod = m; a = a^n; return a.mat[0][1]; } int main() { //freopen("data.in", "r", stdin); LL n; while(cin >> n) { cout << solve(solve(solve(n, l2), l1), 1e9 + 7) << endl; } return 0; }