/* 本题的关键是推递推公式 n - 4 n - 3 n - 2 n - 1 f f m 只能填m f m m 只能填m m f m f 均可以填 m m m f 均可以填 发现n - 1后面填m都可以 F[n] = F[n - 1] + ? 发现n - 1后面填f mmf 可以查到所有 n - 3 的后面 F[n] = F[n - 1] + F[n - 3] + ? 发现n - 1后面填f mff 到 mmff 可以在所有的n - 4的后面 F[n] = F[n - 1] + F[n - 3] + F[n - 4] */ #include <iostream> #include <cstdio> #include <cstring> using namespace std; struct Mat { long long int num[4][4]; Mat() { for(int i = 0; i < 4; i++) for(int j = 0; j < 4; j++) num[i][j] = 0; } }; Mat mul(Mat a, Mat b, int mod) { Mat r; for(int i = 0; i < 4; i++) for(int k = 0; k < 4; k++) { if(a.num[i][k] == 0) continue; for(int j = 0; j < 4; j++) { if(b.num[k][j] == 0) continue; r.num[i][j] = (r.num[i][j] +a.num[i][k] * b.num[k][j]) % mod; } } return r; } Mat mal(Mat a, Mat b, int n, int mod) { while(n) { if(n & 1) { b = mul(a , b, mod); n--; } else { a = mul(a, a, mod); n >>= 1; } } return b; } int main() { int len, mod; int num[6] = {0, 2, 4, 6, 9, 15}; while( scanf("%d %d", &len, &mod) != EOF) { if(len < 5) { printf("%d/n", num[len] % mod); continue; } Mat init, unit; init.num[0][0] = 1; init.num[0][2] = 1; init.num[0][3] = 1; init.num[1][0] = 1; init.num[2][1] = 1; init.num[3][2] = 1; for(int i = 0; i < 4; i++) unit.num[i][0] = num[4 - i]; Mat ans; ans = mal(init, unit, len - 4, mod); printf("%d/n", ans.num[0][0]); } }