首先请连矩阵乘法乘法都还没有了解的同学简单看一下这篇博客:

https://blog.csdn.net/weixin_44049566/article/details/88945949

首先直接暴力求使用O(n)的时间复杂度肯定是不行的,所以我们应该使用更优的时间复杂度。

设f(n)为裴波那契数列第n项。让我们来构造两个矩阵:

和.

现在我们不妨将两个矩阵相乘,化简过后可以得到:,也就是.

如果再将得到的新矩阵乘以,便可以得到。

也就是我们想得到第n项,就可以这么实现:,也就是。

看到幂我们就可以想到快速幂,所以最后程序的时间复杂度便是O(log n)。

代码

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std; #define N 10
#define LL long long int n,mod; struct Matrix {
LL n,m,c[N][N];
Matrix() { memset(c,0,sizeof(c)); };
void _read() {
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
scanf("%lld",&c[i][j]);
}
Matrix operator * (const Matrix& a) {
Matrix r;
r.n=n;r.m=a.m;
for(int i=1;i<=r.n;i++)
for(int j=1;j<=r.m;j++)
for(int k=1;k<=m;k++)
r.c[i][j]= (r.c[i][j]+ (c[i][k] * a.c[k][j])%mod)%mod;
return r;
}
void _print() {
for(int i=1;i<=n;i++) {
for(int j=1;j<=m;j++) {
if(j!=1) cout<<" ";
cout<<c[i][j];
}
if(i!=n) puts("");
}
}
Matrix _power(int indexx) {
Matrix tmp,sum;tmp._pre1();sum._pre1();
while(indexx>0) {
if(indexx&1) sum=sum*tmp;
tmp=tmp*tmp;
indexx/=2;
}
return sum;
}
void _pre1() {
n=m=2;
c[1][1]=0;
c[1][2]=c[2][1]=c[2][2]=1;
}
void _pre2() {
n=1,m=2;
c[1][1]=c[1][2]=1;
} }T,ans; int main() {
cin>>n>>mod;
ans._pre2();
T._pre1();
if(n<=2) { cout<<1; return 0; }
T=T._power(n-3);
ans=ans*T;
cout<<ans.c[1][2];
}
那么前n项之和呢? 这里我们可以这么构造两个矩阵:(S(n)为前n项之和) 和将两个矩阵相乘,剩下的留给读者思考。 这里给出代码: #include <cstdio>
#include <cstring>
#include <iostream>
using namespace std; #define N 10
#define LL long long int n,mod; struct Matrix {
LL n,m,c[N][N];
Matrix() { memset(c,0,sizeof(c)); };
void _read() {
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
scanf("%lld",&c[i][j]);
}
Matrix operator * (const Matrix& a) {
Matrix r;
r.n=n;r.m=a.m;
for(int i=1;i<=r.n;i++)
for(int j=1;j<=r.m;j++)
for(int k=1;k<=m;k++)
r.c[i][j]= (r.c[i][j]+ (c[i][k] * a.c[k][j])%mod)%mod;
return r;
}
void _print() {
for(int i=1;i<=n;i++) {
for(int j=1;j<=m;j++) {
if(j!=1) cout<<" ";
cout<<c[i][j];
}
if(i!=n) puts("");
}
}
Matrix _power(int indexx) {
Matrix tmp,sum;tmp._pre1();sum._pre1();
while(indexx>0) {
if(indexx&1) sum=sum*tmp;
tmp=tmp*tmp;
indexx/=2;
}
return sum;
}
void _pre1() {
n=m=3;
c[3][2]=c[3][3]=c[2][3]=c[1][1]=c[2][1]=c[3][1]=1;
}
void _pre2() {
n=1,m=3;
c[1][1]=2;c[1][3]=c[1][2]=1;
} }T,ans; int main() {
cin>>n>>mod;
if(n==2) return printf("%d",2%mod),0;
if(n==1) return printf("%d",1%mod),0;
ans._pre2();
T._pre1();
if(n<=2) { cout<<1; return 0; }
T=T._power(n-3);
ans=ans*T;
cout<<ans.c[1][1];
}

浅谈矩阵加速——以时间复杂度为O(log n)的算法实现裴波那契数列第n项及前n之和使用矩阵加速法的优化求法的更多相关文章

  1. [矩阵乘法]裴波拉契数列II

    [ 矩 阵 乘 法 ] 裴 波 拉 契 数 列 I I [矩阵乘法]裴波拉契数列II [矩阵乘法]裴波拉契数列II Description 形如 1 1 2 3 5 8 13 21 34 55 89 ...

  2. [矩阵乘法]裴波拉契数列III

    [ 矩 阵 乘 法 ] 裴 波 拉 契 数 列 I I I [矩阵乘法]裴波拉契数列III [矩阵乘法]裴波拉契数列III Description 求数列f[n]=f[n-1]+f[n-2]+1的第N ...

  3. 斐波那契数列第N项f(N)[矩阵快速幂]

    矩阵快速幂 定义矩阵A(m*n),B(p*q),A*B有意义当且仅当n=p.即A的列数等于B的行数. 且C=A*B,C(m*q). 例如: 进入正题,由于现在全国卷高考不考矩阵,也没多大了解.因为遇到 ...

  4. 51nod--1242 斐波那契数列第N项 (矩阵乘法优化)

    题目: 1242 斐波那契数列的第N项 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 收藏 关注 斐波那契数列的定义如下: F(0) = 0 F(1) = 1 F(n) ...

  5. 斐波那契数列F(n)【n超大时的(矩阵加速运算) 模板】

    hihocoder #1143 : 骨牌覆盖问题·一 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 骨牌,一种古老的玩具.今天我们要研究的是骨牌的覆盖问题: 我们有一个 ...

  6. poj3070 求斐波那契数列第n项 ——矩阵快速幂

    题目:http://poj.org/problem?id=3070 用矩阵快速幂加速递推. 代码如下: #include<iostream> #include<cstdio> ...

  7. 【矩阵乘法】【快速幂】【递推】斐波那契数列&&矩乘优化递推模板

    题目大意: F[0]=0 F[1]=1 F[n+2]=F[n+1]+F[n] 求F[n] mod 104. F[n+2] F[n+1] = 1 1 1 0 * F[n+1] F[n] 记这个矩阵为A, ...

  8. HDU4549 M斐波那契数列 矩阵快速幂+欧拉函数+欧拉定理

    M斐波那契数列 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total Sub ...

  9. HDU----(4549)M斐波那契数列(小费马引理+快速矩阵幂)

    M斐波那契数列 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total Sub ...

随机推荐

  1. Date与String互相转换及日期的大小比较

    private static final String PATTERN = "yyyy-MM-dd HH:mm:ss"; /** * String转Date * * @param ...

  2. 2019-11-22-Roslyn-在多开发框架让-msbuild-的-Target-仅运行一次

    title author date CreateTime categories Roslyn 在多开发框架让 msbuild 的 Target 仅运行一次 lindexi 2019-11-22 09: ...

  3. 计蒜客 蓝桥模拟 I. 天上的星星

    计算二维前缀和,节省时间.容斥定理. 代码: #include <cstdio> #include <cstdlib> #include <cstring> #in ...

  4. java实现队列和栈

    队列:队列其实就是我们生活中的排队现象,先进入的先出,后进入的后出,代码实现如下: public class Queue<E> { private int front;//队头一端,只允许 ...

  5. Facebook再现丑闻,约100位应用程序开发人员偷看用户数据

    Facebook今天披露了另一起安全事件,承认大约100名应用程序开发人员可能不正确地访问了某些Facebook组中的用户数据,包括他们的姓名和个人资料图片. 在周二发布的博客文章中,Facebook ...

  6. LeetCode--015--三数之和(python)

    给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组. 先对nums进行排序,再用双指针,L ...

  7. shell练习--PAT题目1001:卡拉兹(Callatz)猜想(失败案例)

    卡拉兹(Callatz)猜想: 对任何一个正整数 n,如果它是偶数,那么把它砍掉一半:如果它是奇数,那么把 ( 砍掉一半.这样一直反复砍下去,最后一定在某一步得到 n=1.卡拉兹在 1950 年的世界 ...

  8. SpringBoot搭建基于Spring+SpringMvc+Mybatis的REST服务

    Maven Plugin管理 通常,让你的Maven POM文件继承 spring-boot-starter-parent,并声明一个或多个 Starter POMs依赖即可. spring-boot ...

  9. Bugku web web2

    web2 打开后发现是个大滑稽啊!F12检查元素拿到flag

  10. CodeForces 1198C 1199E Matching vs Independent Set

    Time limit 1000 ms Memory limit 262144 kB 这题是一场cf里,div1的第三题,div2的第5题 中文题意 给一张无向图,没说连通性,要你选出一个大小为n的匹配 ...