hdu4291 A Short problem(矩阵快速幂+循环节)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4291
题目意思:求g(g(g(n))) mod 109 + 7,其中g(n) = 3g(n - 1) + g(n - 2),g(1) = 1,g(0) = 0。
思路:一个很简单的矩阵快速幂,简单的想法就是先用n算出g(n),然后再算g(g(n)),然后再算最外层,都是mod(1e9+7),这么做就错了,这道题有一个循环节的问题,看来这种嵌套的递推式取mod是存在循环节的,以后要注意下。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define ll long long const int N = 2; ll n; struct Matrix{ ll mat[N][N]; ll MOD; Matrix operator*(const Matrix& m)const{ Matrix tmp; tmp.MOD = MOD; for(int i = 0 ; i < N ; i++){ for(int j = 0 ; j < N ; j++){ tmp.mat[i][j] = 0; for(int k = 0; k < N ; k++) tmp.mat[i][j] += mat[i][k]*m.mat[k][j]%MOD; tmp.mat[i][j] %= MOD; } } return tmp; } }; ll Pow(Matrix m , ll x , ll MOD){ if(x <= 1) return x; Matrix ans; ans.MOD = m.MOD = MOD; ans.mat[0][0] = ans.mat[1][1] = 1; ans.mat[1][0] = ans.mat[0][1] = 0; x--; while(x){ if(x%2) ans = ans*m; x /= 2; m = m*m; } return ans.mat[0][0]%MOD; } int main(){ ll L1 = 1e9+7; ll L2 = 222222224; ll L3 = 183120; Matrix m; m.mat[0][0] = 3; m.mat[1][1] = 0; m.mat[0][1] = 1; m.mat[1][0] = 1; while(scanf("%lld" , &n) != EOF){ ll x = Pow(m , n , L3); ll y = Pow(m , x , L2); ll ans = Pow(m , y , L1); printf("%lld\n" , ans); } return 0; }