矩阵乘法快速幂 斐波那契数

矩阵运算 + 快速幂。

快速幂算法的模板可以参考这里。
用算法4我们1秒内最多可以算到 108
级别,那当 n 更大时该怎么办呢?
可以先利用矩阵运算的性质将通项公式变成幂次形式,然后用平方倍增(快速幂)的方法求解第 n

项。

首先我们定义向量
Xn=[anan−1],边界:X1=[a1a0]

然后我们可以找出矩阵:
A=[1110]

则有:
Xn=Xn−1×A

所以:

Xn=X1×An−1

由于矩阵具有结合律,所以我们可以先求出 An−1%P
,然后再用 X1 左乘,即可求出 Xn,向量 Xn 的第一个元素就是 an

时间复杂度分析:快速幂的时间复杂度是 O(logn)
,所以算法5的时间复杂度也是 O(logn)。

根据斐波那契数项之间的关系构造矩阵。
矩阵形如{fn,fn+1,sn}。

扫描二维码关注公众号,回复: 9567300 查看本文章
#include<bits/stdc++.h>
using namespace std;
const   int N=3;
int n,m;
int a[N][N]={{0,1,0},{1,1,1},{0,0,1}},f[N]={1,1,1};
void mul1(int a[],int b[][N],int c[])
{
    int temp[N]={0};
    for(int i=0;i<N;i++)
    for(int j=0;j<N;j++)
    temp[i]=(temp[i]+(long long)a[j]*b[j][i])%m;
    memcpy(c,temp,sizeof temp);
}
void mul2(int a[][N],int b[][N],int c[][N])//第二维大小要定义
{
 int  temp[N][N]={0};
for(int i=0;i<N;i++)
for(int j=0;j<N;j++)
for(int k=0;k<N;k++)
temp[i][j]=(temp[i][j]+(long long)a[i][k]*b[k][j])%m;
memcpy(c,temp,sizeof temp);
}
int main()
{
    cin>>n>>m;
    n--;
    while(n)
    {
        if(n&1)mul1(f,a,f);
        mul2(a,a,a);
        n>>=1;
    }
    cout<<f[2]<<endl;
    return 0;
    
}
发布了122 篇原创文章 · 获赞 8 · 访问量 1994

猜你喜欢

转载自blog.csdn.net/qq_45961321/article/details/104647621
今日推荐