1303. 斐波那契前 n 项和 - AcWing题库
构造矩阵A使
0 1 0
A = [ 1 1 1 ]
0 0 1
然后对这个式子进行快速幂,挺神奇的
#include<bits/stdc++.h>
#define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define endl '\n'
using namespace std;
typedef pair<int, int> PII;
typedef long long ll;
typedef long double ld;
const int N = 3;
int n, mod;
void mul(int C[], int A[], int B[][N])
{
int tmp[N] = {0};
for(int i = 0; i < N; i ++)
for(int j = 0; j < N; j ++)
tmp[i] = (tmp[i] + (ll)A[j] * B[j][i]) % mod;
memcpy(C, tmp, sizeof tmp);
}
void mul(int C[][N], int A[][N], int B[][N])
{
int tmp[N][N] = {0};
for(int i = 0; i < N; i ++)
for(int j = 0; j < N; j ++)
for(int k = 0; k < N; k ++)
tmp[i][j] = (tmp[i][j] + (ll)A[i][k] * B[k][j]) % mod;
memcpy(C, tmp, sizeof tmp);
}
int main()
{
IOS
int f1[N] = {1, 1, 1};
int A[N][N] = {{0, 1, 0}, {1, 1, 1}, {0, 0, 1}};
cin >> n >> mod;
int k = n - 1;
while(k)
{
if(k & 1)mul(f1, f1, A);//f1 = f1 * A
mul(A, A, A);//A = A * A
k >>= 1;
}
cout << f1[2];
return 0;
}