【矩阵快速幂】 斐波那契前n项和
传送门
题意
给定 n和mod,求出前n 项斐波那契的和,结果模mod
数据范围
\(1\leq n\leq 2\times 10^{9}\)
\(1\leq mod\leq 1000000010\)
题解
数据范围很大只能接受 \(O (\sqrt{n})\) 或者 \(O(log n)\)的
矩阵递推加速,f(n) 三维行向量表示为
\[\left( f(n) ,f(n+1) ,s(n) \right)
\]
转移矩阵为:
\[\left( \begin{array}{l} 0 & 1 & 0 \\ 1 & 1 & 1 \\0 & 0 & 1\end{array} \right)
\]
矩阵快速幂复杂度为\(O(3\times logn)\),满足要求
Code
#include <bits/stdc++.h>
using namespace std;
#define rep(i, a, n) for(int i = a; i < n; i ++)
#define ll long long
int n, mod;
void mul(int f[4], int a[4][4])
{
int t[4]; memset(t, 0, sizeof t);
rep(i, 0, 4) rep(k, 0, 4)
t[i]=(t[i]+ 1ll * f[k] * a[k][i])%mod;
memcpy(f, t, sizeof t);
}
void mulself(int p[4][4])
{
int t[4][4]; memset(t, 0, sizeof t);
rep(i, 0, 4) rep(j, 0, 4) rep(k, 0, 4)
t[i][j]=(t[i][j]+1ll * p[i][k] * p[k][j])%mod;
memcpy(p, t, sizeof t);
}
int main()
{
cin>>n>>mod;
int p[4][4] =
{
{0, 1, 0, 0},
{1, 1, 1, 0},
{0, 0, 1, 1},
{0, 0, 0, 1}
};
int f[4] = {1, 1, 1, 0};
int k = n - 1;
while(k)
{
if(k & 1) mul(f, p);
mulself(p);
k >>= 1;
}
cout<<( ( (1ll * n * f[2]) % mod - f[3]) % mod + mod) % mod<<endl;
return 0;
}

浙公网安备 33010602011771号