【矩阵快速幂+循环节】HDU 5451 Best Solver
题意:计算(5+26√)1+2^x.
思路:循环节是(p+1)*(p-1),然后就是裸的矩阵快速幂啦。
代码:
#include<cmath> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; typedef long long ll; const int N = 2; int MOD; struct Matrix{ ll mat[N][N]; Matrix operator*(const Matrix& m)const{ Matrix tmp; 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 k){ if(k == 1) return 9; k--; Matrix ans; memset(ans.mat , 0 , sizeof(ans.mat)); for(int i = 0 ; i < N ; i++) ans.mat[i][i] = 1; // printf("%d\n", k); while(k){ if(k&1) ans = ans*m; k >>= 1; m = m*m; } // out(ans); ll x = (ans.mat[0][0]*5+ans.mat[0][1]*2)%MOD; return (x * 2-1)%MOD; } ll NOW; ll Pow(int x) { ll res = 1, two = 2; while (x > 0) { if (x & 1) res = (res * two) % NOW; two = (two * two) % NOW; x >>= 1; } return res; } int main(){ int T; Matrix m; scanf("%d" , &T); int cas = 0; while(T-- > 0) { int n; scanf("%d%d" , &n, &MOD); NOW = (MOD + 1) * (MOD - 1); ll nn = Pow(n) + 1 ; m.mat[0][0] = 5 ; m.mat[0][1] = 12; m.mat[1][0] = 2 ; m.mat[1][1] = 5; printf("Case #%d: %I64d\n" , ++cas, Pow(m , nn)); } }