題目:
解題思路:
暴搜搜出前面幾個的答案
然後枚舉每一項的係數再枚舉一個常數項推出規律
規律:
然後將搜索出來的前四項帶入
矩陣乘法優化
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
typedef long long ll;
int n, m, Ans;
ll a[10][10], t[10][10], ans[10][10];
bool read(int &x, int &y) {
x = y = 0; char c = getchar();
while (!isdigit(c)) c = getchar();
while (isdigit(c)) x = x * 10 + c - 48, c = getchar();
while (!isdigit(c)) c = getchar();
while (isdigit(c)) y = y * 10 + c - 48, c = getchar();
return x + y;
}
void Matrix(int flag) {
memset(ans, 0, sizeof(ans));
for (int i = 1; i <= 4; i++) {
for (int j = 1; j <= 4; ++j) {
for (int k = 1; k <= 4; ++k) {
ans[i][j] += (t[i][k]*(flag==1?a[k][j]:t[k][j]) + m) % m;
ans[i][j] %= m;
}
}
}
for (int i = 1; i <= 4; ++i)
for (int j = 1; j <= 4; ++j)
if (flag) a[i][j] = ans[i][j];
else t[i][j] = ans[i][j];
}
ll fuck(ll n) {
t[1][1] = 1, t[1][2] = 5, t[1][3] = 1, t[1][4] = -1;
t[2][1] = 1, t[2][2] = 0, t[2][3] = 0; t[2][4] = 0;
t[3][1] = 0; t[3][2] = 1; t[3][3] = 0; t[3][4] = 0;
t[4][1] = 0; t[4][2] = 0; t[4][3] = 1; t[4][4] = 0;
while(n) {
if (n & 1) Matrix(1);
Matrix(0);
n >>= 1;
}
return a[1][1];
}
int main() {
while(read(n, m)) {
if(n == 1) Ans = 1;
else if(n == 2) Ans = 5;
else if(n == 3) Ans = 11;
else if(n == 4) Ans = 36;
else {
memset(a, 0, sizeof(a));
a[1][1] = 36;
a[2][1] = 11;
a[3][1] = 5;
a[4][1] = 1;
Ans = fuck(n - 4);
}
printf("%d\n", Ans % m);
}
return 0;
}