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

    传送门

    斐波那契数列

    看一眼果断递推

    f[ i ] = f[ i-1 ] + f[ i-2 ] 嘛

    数据一看..

    好像不行....

    那就矩阵优化一下嘛

    最基础的矩阵乘法嘛 (不懂先学一下 矩阵乘法 吧)

    稍微想一想:

    设矩阵为 A

    那么矩阵 [  f[i-2]   ,   f[i-1]  ] * A 要等于 [  f[i-1]   ,   f[i]  ](即要等于 [ f[i-1]   ,   f[i-1]+f[i-2]  ])

    在纸上稍微画一下就得到 A 了 (随便挂一下当初学构造矩阵的链接: 传送门

    A = [ 0,1 ]

        [ 1,1 ]

    然后就可以把 初始矩阵乘上 n 个 A

    显然初始矩阵为[ 1,1 ](设为B)

    那么答案就是B*A*...*A(一共n-1个A)

    因为矩阵乘法满足结合律

    所以变一下就是B*(A^n)

    然后就可以用快速幂来求A^n啦

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    using namespace std;
    typedef long long ll;
    const ll mo=1000000007;
    ll x;
    struct matrix
    {
        ll a[3][3];
        matrix(){ memset(a,0,sizeof(a)); }
        matrix operator * (matrix &tmp){
            matrix c;
            for(int i=1;i<=2;i++)
                for(int j=1;j<=2;j++)
                    for(int k=1;k<=2;k++)
                        c.a[i][j]=(c.a[i][j]+(a[i][k]*tmp.a[k][j])%mo)%mo;
            return c;
        }//重载一下乘号
    }Ans,y;
    int main()
    {
        Ans.a[1][1]=Ans.a[1][2]=1;
        y.a[1][2]=y.a[2][1]=y.a[2][2]=1;
        cin>>x; x--;
        while(x)
        {
            if(x&1) Ans=Ans*y;
            y=y*y;
            x>>=1;
        }//重载了乘号就可以直接快速幂了
        cout<<Ans.a[1][1];//矩阵的第一项就是答案
        return 0;
    }
  • 相关阅读:
    Linux内核tracepoints
    Linux 设备驱动的固件加载
    Android HIDL HAL 接口定义语言详解
    Android HIDL 详解
    Android各版本对应的SDK版本
    ifconfig调用过程
    Input系统—启动篇
    Linux下2号进程的kthreadd--Linux进程的管理与调度
    rest_init函数分析(续)
    【python】-常用模块2
  • 原文地址:https://www.cnblogs.com/LLTYYC/p/9581310.html
Copyright © 2011-2022 走看看