AcWing 1303. 斐波那契前 n 项和
原题链接
中等
作者:
wjie
,
2020-07-04 23:34:33
,
所有人可见
,
阅读 562
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long LL;
struct Matrix{
LL mat[4][4];
}answer;
void show(Matrix a)
{
for (int i = 1; i <= 3; ++i)
{
for (int j = 1; j <= 3; ++j)
cout << a.mat[i][j] << " ";
cout << endl;
}
}
Matrix Multiple(Matrix a, Matrix b, int c)
{
Matrix res;
memset(res.mat, 0, sizeof(res.mat));
for (int i = 1; i <= 3; ++i)
{
for (int j = 1; j <= 3; ++j)
{
for (int k = 1; k <= 3; ++k)
{
LL tmp = a.mat[i][k] * b.mat[k][j] % c;
res.mat[i][j] = (res.mat[i][j] + tmp) % c;
}
}
}
return res;
}
Matrix expMod(Matrix a, int b, int c)
{
Matrix res;
memset(res.mat, 0, sizeof(res.mat));
res.mat[1][1] = res.mat[2][2] = res.mat[3][3] = 1;
while (b)
{
if (b & 1)
res = Multiple(res, a, c);
a = Multiple(a, a, c);
b >>= 1;
}
return res;
}
int main()
{
int n, m;
scanf("%d %d", &n, &m);
answer.mat[1][2] = answer.mat[1][3] = 1;
answer.mat[2][1] = answer.mat[2][2] = answer.mat[2][3] = 1;
answer.mat[3][3] = 1;
// show(answer);
// show(Multiple(answer, answer, 1000));
answer = expMod(answer, n-2, m);
LL ans = 0;
for (int i = 1; i <= 2; ++i)
ans = (ans + answer.mat[i][3]) % m;
ans = (ans + answer.mat[3][3]*2%m) % m;
printf("%lld", ans);
// show(answer);
return 0;
}