HDU-4291 A Short problem 嵌套循环节+矩阵快速幂
将gg(n)视为一个未知元,先由1000000007找出循环节222222224,然后再找出g(n)为变量时的循环节183120,然后应用矩阵快速幂求解即可。
代码如下:
#include<iostream> #include<cstdio> #include<cstdlib> #include<algorithm> #include<cmath> #include<queue> #include<set> #include<map> #include<cstring> #include<vector> #include<string> using namespace std; typedef long long Int64; int MOD; struct Matrix { Int64 a[2][2]; inline Matrix () { memset(a, 0, sizeof (a)); } inline Matrix(int _a, int b, int c, int d) { a[0][0] = _a, a[0][1] = b; a[1][0] = c, a[1][1] = d; } inline Matrix operator * (Matrix y) { Matrix ret; for (int i = 0; i < 2; ++i) { for (int j = 0; j < 2; ++j) { for (int k = 0; k < 2; ++k) { ret.a[i][j] += (a[i][k] * y.a[k][j]) % MOD; } ret.a[i][j] %= MOD; } } return ret; } inline Matrix pow_mod(Int64 b, int mod) { Matrix ret(1, 0, 0, 1); MOD = mod; while (b) { if (b & 1) { ret = ret * *this; } *this = *this * *this; b >>= 1; } return ret; } }; // 222222224 第一个循环节,表示g[222222224]%MOD = 0, g[222222225]%MOD = 1 // 再将222222224作为MOD数,寻找下一个循环节 // 下一个循环节是 183120,原因同上 // 找到循环节后就是矩阵快速幂了 inline Int64 solve(Int64 x, int mod) { if (x == 0) return 0; Matrix r(3, 1, 1, 0); return r.pow_mod(x-1, mod).a[0][0]; } int main( ) { Int64 N; while (scanf("%I64d", &N) == 1) { printf("%I64d\n", solve(solve(solve(N, 183120), 222222224), 1000000007)); } return 0; }