洛谷P1962 斐波那契数列【矩阵运算】


题目背景

大家都知道,斐波那契数列是满足如下性质的一个数列:

• f(1) = 1

• f(2) = 1

• f(n) = f(n-1) + f(n-2) (n ≥ 2 且 n 为整数)

题目描述

请你求出 f(n) mod 1000000007 的值。

输入格式:

·第 1 行:一个整数 n

输出格式:

第 1 行: f(n) mod 1000000007 的值

输入样例1

5

输出样例1

5

输入样例2

10

输出样例2

55

说明

对于 60% 的数据: n ≤ 92

对于 100% 的数据: n在long long(INT64)范围内。


题解分析:

这题主要的难点就在超大的数据范围

” n在long long(INT64)范围内。”

直接递推什么的肯定是不行的

所以这时候我们的矩阵运算就派上用场啦

我们依次将斐波那契数放入矩阵

[f(1)f(2)](1)
[f(2)f(3)](2)
[f(3)f(4)](3)

一号矩阵是已知的

那么要怎样推出后面的矩阵呢

我们试着用1矩阵乘以下面这个矩阵A

[0111](A)

发现是不是得到了二号矩阵

再用二号矩阵去乘A矩阵

是不是得到了三号?

(真的是妙啊~妙啊~)

由此不难找出规律

f(n)第一次出现的地方

就是算出A^(n-2)再乘以原斐波那契初始矩阵

最后要求的f(n)一定在答案矩阵的最下面的位置

所以总结起来

矩阵运算的题目

就是像这样找出一个初始矩阵

然后便可以运用该矩阵进行优化运算


规律应该很清楚了吧

代码里就不写什么注释了

(就是懒 = =)

#include<iostream>
#include<cstdio>
#include<vector>
#include<algorithm>
#include<queue>
#include<cstring>
using namespace std;
typedef long long ll;

ll read()
{
    ll f=1,x=0;
    char ss=getchar();
    while(ss<'0'||ss>'9'){if(ss=='-')f=-1;ss=getchar();}
    while(ss>='0'&&ss<='9'){x=x*10+ss-'0';ss=getchar();}
    return f*x;
}

void print(ll x)
{
    if(x<0){putchar('-');x=-x;}
    if(x>9)print(x/10);
    putchar(x%10+'0');
}

const ll mod=1000000007;
ll n;
struct node
{
    ll a[5][5];
    node()
    {
        for(ll i=1;i<=2;i++)
        for(ll j=1;j<=2;j++)
        a[i][j]=0;
    }//初始化矩阵
}d,fibo;
ll res[10][10];

node quick_pow(node f,ll k)
{
    if(k==1) return f;

    else if(k%2==1)
    {
        node temp=quick_pow(f,k-1);
        node ans;
        for(ll i=1;i<=2;i++)
        for(ll j=1;j<=2;j++)
        for(ll k=1;k<=2;k++)
        ans.a[i][j]+=(f.a[i][k]*temp.a[k][j])%mod,ans.a[i][j]%=mod;
        return ans;
    }

    else if(k%2==0)
    {
        node temp=quick_pow(f,k/2);
        node ans;
        for(ll i=1;i<=2;i++)
        for(ll j=1;j<=2;j++)
        for(ll k=1;k<=2;k++)
        ans.a[i][j]+=(temp.a[i][k]*temp.a[k][j])%mod,ans.a[i][j]%=mod;
        return ans;
    }
}

int main()
{
    n=read();
    if(n==1||n==2){print(1);return 0;}
    //记得特判
    fibo.a[1][1]=1; fibo.a[2][1]=1;
    d.a[1][1]=0; d.a[1][2]=1;
    d.a[2][1]=1; d.a[2][2]=1;
    //运算用的矩阵

    ll k=n-2;
    node temp=quick_pow(d,k);
    //先计算A矩阵的n-2次幂

    for(ll i=1;i<=2;i++)
    for(ll j=1;j<=1;j++)
    for(ll k=1;k<=2;k++)
    res[i][j]+=(temp.a[i][k]*fibo.a[k][j])%mod,res[i][j]%=mod;
    //与f(1)与f(2)的矩阵相乘得出最后答案矩阵

    print(res[2][1]);

    return 0;
}

洛谷P1962 斐波那契数列【矩阵运算】的更多相关文章

  1. 洛谷P1962 斐波那契数列 || P1349 广义斐波那契数列[矩阵乘法]

    P1962 斐波那契数列 大家都知道,斐波那契数列是满足如下性质的一个数列: • f(1) = 1 • f(2) = 1 • f(n) = f(n-1) + f(n-2) (n ≥ 2 且 n 为整数 ...

  2. 洛谷——P1962 斐波那契数列

    P1962 斐波那契数列 题目背景 大家都知道,斐波那契数列是满足如下性质的一个数列: • f(1) = 1 • f(2) = 1 • f(n) = f(n-1) + f(n-2) (n ≥ 2 且 ...

  3. 洛谷—— P1962 斐波那契数列

    https://www.luogu.org/problem/show?pid=1962 题目背景 大家都知道,斐波那契数列是满足如下性质的一个数列: • f(1) = 1 • f(2) = 1 • f ...

  4. 洛谷P1962 斐波那契数列(矩阵快速幂)

    题目背景 大家都知道,斐波那契数列是满足如下性质的一个数列: • f(1) = 1 • f(2) = 1 • f(n) = f(n-1) + f(n-2) (n ≥ 2 且 n 为整数) 题目描述 请 ...

  5. 洛谷P1962 斐波那契数列题解

    题目背景 大家都知道,斐波那契数列是满足如下性质的一个数列: • f(1) = 1 • f(2) = 1 • f(n) = f(n-1) + f(n-2) (n ≥ 2 且 n 为整数) 题目描述 请 ...

  6. 【洛谷P1962 斐波那契数列】矩阵快速幂+数学推导

    来提供两个正确的做法: 斐波那契数列双倍项的做法(附加证明) 矩阵快速幂 一.双倍项做法 在偶然之中,在百度中翻到了有关于斐波那契数列的词条(传送门),那么我们可以发现一个这个规律$ \frac{F_ ...

  7. 洛谷 P1962 斐波那契数列

    题目链接:https://www.luogu.org/problemnew/show/P1962 题目大意: 略 分析: 由于数据规模很大,需要用矩阵快速幂来解. 代码如下: #pragma GCC ...

  8. 题解——洛谷P1962 斐波那契数列(矩阵乘法)

    矩阵乘法加速线性递推的典型 大概套路就是先构造一个矩阵\( F \)使得另一初始矩阵\( A \)乘以\( F^{x} \)能够得出第n项 跑的飞快 虽然我也不知道那个矩阵要怎么构造 或许就像我使用了 ...

  9. 洛谷P1962 斐波那契数列

    传送门 不难得到状态转移矩阵 然后带进去乱搞 //minamoto #include<iostream> #include<cstdio> #include<cstrin ...

随机推荐

  1. python爬虫知乎

    在之前写过一篇使用python爬虫爬取电影天堂资源的博客,重点是如何解析页面和提高爬虫的效率.由于电影天堂上的资源获取权限是所有人都一样的,所以不需要进行登录验证操作,写完那篇文章后又花了些时间研究了 ...

  2. 疑难杂症——关于EntityFramework的SqlQuery方法的执行效率差异的探讨

    前言:最近项目上面遇到一个问题,在Code First模式里面使用EntityFramework的SqlQuery()方法查询非常慢,一条数据查询出来需要10秒以上的时间,可是将sql语句放在plsq ...

  3. 使用Python查询JMX

    一.介绍 我们知道 java 项目中的 JMX 接口信息是十分有用的,我们可以提取这些信息来分析或告警.但是 JMX 的 API 只在 java 中实现,因此,找到一个 Python 代码调用 Jav ...

  4. 创建一个离线优先,数据驱动的渐进式 Web 应用程序

    原文地址:Build an offline-first, data-driven PWA 译文出自:我的个人博客 概述 在本文中,您将学习如何使用 Workbox 和 IndexedDB 创建离线优先 ...

  5. centos7安装python3.6

    安装python3.6可能使用的依赖 # yum install openssl-devel bzip2-devel expat-devel gdbm-devel readline-devel sql ...

  6. Python简单爬虫Requests

    首先添加库 附配环境变量:安装环境变量 cmd==> 输入指令: path=%path%;C:\Python(Python安装路径) 回车 python2.7版本可能没有pip的话可以先到www ...

  7. 基于百度地图SDK和Elasticsearch GEO查询的地理围栏分析系统(3)-前端实现

    转载自:http://www.cnblogs.com/Auyuer/p/8086975.html MoonLight可视化订单需求区域分析系统实现功能: 在现实生活中,计算机和互联网迅速发展,人们越来 ...

  8. SQL语句-INSERT语句

    Insert语句 Insert语句三种写法: mysql> desc students; +-------+-------------+------+-----+---------+------ ...

  9. Node.js系列-express(上)

    前言 Node.js系列的第一篇:http,大概描述了通过使用node.js内置的api创建一个服务并监听request实现简单的增删改查.现在,我们就通过通读express官网及使用express框 ...

  10. PostgreSQL版本快速升级

    PostgreSQL版本快速升级 写在前面 PostgreSQL9.5版本支持数据分片的功能,为以后做分布式考虑,准备将生产环境的9.1版本升级至9.5.中间需要做数据迁移. 在迁移操作中,为保证数据 ...