長い時間、問題の無い書き込み行列乗算最適化された再発は、非常にでこぼこ書きます。
まず、私たちが聞いて、すべてのは、ということです\(\ SUM私F_iとは、\) 。そして、このことは、再帰的にすることはできません。GMKはI + 1カンカンに私を教えています。
\((i+1)F_{i+1}=(i + 1)(F_i + F_{i -1})=iF_i + F_i + (i - 1)F_{i -1} + 2F_{i - 1}\)。这玩意就可以用矩阵啦。
この質問を書くことは過ちSBの束を作りました。。。
1.オーバーロードされた乗算は(返されませんでしたか?
ときに長い時間のために書かれた係数2 1曲2.遷移行列を書きます。。。
3.私の電源はすぐに、N-2からカウントを始め、1つの特別に刑を宣告されました。。。堅牢性の欠如
#include <bits/stdc++.h>
#define ll long long
ll n, p;
struct Matrix {
ll a[10][10];
Matrix() { memset(a, 0, sizeof(a)); }
void QAQ() {
a[1][1] = a[2][1] = a[3][1] = a[4][2] = a[1][3] = a[2][2] = a[2][4] = a[1][5] = a[5][5] = 1,
a[4][1] = 2;
}
friend Matrix operator*(Matrix x, Matrix y) {
Matrix z;
for (int k = 1; k <= 5; k++)
for (int i = 1; i <= 5; i++)
for (int j = 1; j <= 5; j++) z.a[i][j] = (z.a[i][j] + x.a[i][k] * y.a[k][j]) % p;
return z;
}
};
Matrix qpow(Matrix x, int b) {
Matrix ret = x;
for (; b; b >>= 1, x = x * x)
if (b & 1)
ret = ret * x;
return ret;
}
signed main() {
scanf("%lld%lld", &n, &p);
if (n == 1) {
puts("1");
return 0;
}
Matrix tmp;
tmp.QAQ();
Matrix ans;
ans.a[1][1] = 2, ans.a[1][2] = 1, ans.a[1][3] = ans.a[1][4] = 1, ans.a[1][5] = 1;
tmp = qpow(tmp, n - 2);
ans = ans * tmp;
printf("%lld\n", ans.a[1][5]);
return 0;
}