题436. 矩阵乘法-acwing-1303. 斐波那契前 n 项和
一、题目
二、题解
先考虑采用一般的法子去求解斐波那契的前n项和,易知时间复杂度为O(n),但是这里n非常大,直接就会超时了,因此我们想如何加速计算。
考虑构造如下等式:
则有:
则根据递推式我们可以得到:
这样,我们可通过矩阵快速幂求解Fn,然后取Fn[2]=s(n)即可
代码如下:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=3;
int n,m;
void mul(int c[],int a[],int b[][maxn])
{
int tmp[maxn]={0};
for(int i=0;i<maxn;i++)
{
for(int j=0;j<maxn;j++)
{
tmp[i]=(tmp[i]+(ll)a[j]*b[j][i])%m;
}
}
memcpy(c,tmp,sizeof tmp);
}
void mul(int c[][maxn],int a[][maxn],int b[][maxn])
{
int tmp[maxn][maxn]={0};
for(int i=0;i<maxn;i++)
{
for(int j=0;j<maxn;j++)
{
for(int k=0;k<maxn;k++)
{
tmp[i][j]=(tmp[i][j]+(ll)a[i][k]*b[k][j])%m;
}
}
}
memcpy(c,tmp,sizeof tmp);
}
int main()
{
cin>>n>>m;
int F[maxn]={1,1,1};//F={f(1),f(2),s(1)}
//构造出的矩阵a,使得F*a=[f(n),f(n+1),s(n)]*a=[f(n+1),f(n+2),s(n+1)]
int a[maxn][maxn]={
{0,1,0},
{1,1,1},
{0,0,1}
};
n--;//欲求前n项和,实际是求F*a^(n-1)
while(n)//矩阵快速幂
{
if(n&1) mul(F,F,a);//F=F*a
n>>=1;//n/2
mul(a,a,a);//a=a*a
}
cout<<F[2];
}