zoukankan      html  css  js  c++  java
  • 洛谷P1962 斐波那契数列

    题目:https://www.luogu.org/problemnew/show/1962

    题目背景

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

    • 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)范围内。

    解析

    给了60分的暴力分,美滋滋= ̄ω ̄=

    那么剩下的40分怎么办Σ( ° △ °|||)︴

    别告诉我你要打一个辣么大的表( ﹁ ﹁ ) ~→

    好吧,这就需要一个重要的知识点叫做矩阵乘法。

    矩阵乘法不会的,请咨询度娘吧23333333333333.

    矩阵乘法满足结合律哦。

    我们可以把状态转移方程转化成矩阵相乘,然后,

    中间乘的矩阵都是一样的哦。

    那么,想到什么了吗(⊙ω⊙)

    对啦,就是快速幂啦(∩_∩)

    矩阵快速幂与快速幂的做法很相似哦!相信大佬们一定会的(~ ̄▽ ̄)~

    好了,蒟蒻的代码如下了:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<cmath>
     6 using namespace std;
     7 #define ll long long
     8 #define mod 1000000007
     9 struct submix{
    10     ll a[5][5];
    11 };
    12 submix operator * (submix x,submix y){
    13     submix res;
    14     memset(res.a,0,sizeof(res.a));
    15     for (ll k=1;k<=2;++k){
    16         for (ll i=1;i<=2;++i){
    17             for (ll j=1;j<=2;++j){
    18                 res.a[i][j]=(res.a[i][j]+x.a[i][k]*y.a[k][j])%mod;
    19             }
    20         }
    21     } 
    22     return res;
    23 } 
    24 ll f[1010];
    25 ll n;
    26 submix ori,enm;
    27 submix ksm(submix x,ll k){
    28     submix res=ori;
    29     while (k){
    30         if (k&1){
    31             res=res*x;
    32         }
    33         x=x*x;
    34         k=k/2;
    35     }
    36     return res;
    37 }
    38 int main(){
    39     cin>>n;
    40     if (n==1){
    41         cout<<"1";
    42         return 0;
    43     }
    44     if (n==2){
    45         cout<<"1";
    46         return 0;
    47     }
    48     ori.a[1][1]=1;
    49     ori.a[1][2]=1;
    50     ori.a[2][1]=1;
    51     ori.a[2][2]=0;
    52     enm=ksm(ori,n-3);
    53     /*cout<<enm.a[1][1]<<endl;
    54     cout<<enm.a[1][2]<<endl;
    55     cout<<enm.a[2][1]<<endl;
    56     cout<<enm.a[2][2]<<endl;*/
    57     cout<<(enm.a[1][1]+enm.a[2][1])%mod;
    58     return 0;
    59 }
    View Code

    注释语句是我检验输出的,就无视掉吧233

  • 相关阅读:
    Windows环境下多版本JDK切换
    科学记数法数字转换/保留数值小数点位数(数字格式化)
    解析Excel数据
    odoo 配置文件参数大全
    odoo10 addon开发流程
    odoo10源码 windows环境安装
    【12】Django 中间件
    【10】Cookie和Session
    django-debug-toolbar
    爬虫系列之mongodb
  • 原文地址:https://www.cnblogs.com/gjc1124646822/p/7795524.html
Copyright © 2011-2022 走看看