zoukankan      html  css  js  c++  java
  • HDU2855—Fibonacci Check-up

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2855

    题目意思:求一个式子g[n]=∑C(n,k)*f[k],n很大,很明显是一个矩阵快速幂。可以打表发现g[n]=f[2*n]划开可以发现g[n]=3*g[n-1]-f[n-2]。

    思路:我们现在可以证明一下

    f[2*n]=f[2*n-1]+f[2*n-2];

    其中f[2*n-1]=f[2*n-2]+f[2*n-3]

    f[2*n-2]=f[2*n-3]+f[2*n-4]

    所以f[2*n]=f[2*n-2]+f[2*n-3]+f[2*n-3]+f[2*n-4]=2*f[2*n-2]+f[2*n-3]=2*f[2*n-2]+f[2*n-3]+f[2*n-4]-f[2*n-4]=3*f[2*n-2]-f[2*n-4]。我们化简一下g[n]=3*g[n-1]-g[n-2]。我们可以通过打表得到这个结论。

    现在我们可以从数学上证明一下这个结论。

    方法:1.通项公式:f[n]=(1/sqrt(5))*(((1+sqrt(5))/2)^n-((1-sqrt(5))/2)^n)  

       2.二项式:(1+a)^n=∑(C(n,k)*a^k)(0<=k<=n)

    ∑C(n,k)*f[k]=(1/sqrt(5))*∑C(n,k)*(((1+sqrt(5))/2)^k-((1-sqrt(5))/2)^k)

         =(1/sqrt(5))*(∑C(n,k)*((1+sqrt(5))/2)^k-∑C(n,k)*((1-sqrt(5))/2)^k) 

         =(1/sqrt(5))*((3+sqrt(5))/2)^n-((3-sqrt(5))/2)^n) 

         =(1/sqrt(5))*((1+sqrt(5))/2)^(2*n)-((1-sqrt(5))/2)^(2*n))

         =f[2*n] 

    这个组合数的应用感觉十分有意思。

    代码:

    //Author: xiaowuga
    #include<bits/stdc++.h>
    #define maxx INT_MAX
    #define minn INT_MIN
    #define inf 0x3f3f3f3f
    #define N  2
    using namespace std;
    long long MOD;
    typedef long long ll;
    ll  n,size=2;//第n项,矩阵大小
    struct Matrix{
        ll mat[N][N];
        void clear(){
            memset(mat,0,sizeof(mat));
        }
        Matrix operator * (const Matrix & m) const{
            Matrix tmp;
            int i ,j,k;
            tmp.clear();
            for( i=0;i<size;i++)
                for( k=0;k<size;k++){
                    if(mat[i][k]==0) continue;
                    for( j=0;j<size;j++){
                        tmp.mat[i][j]+=mat[i][k]*m.mat[k][j]%MOD;
                        tmp.mat[i][j]%=MOD;
                    }
                }
            return tmp;
        }
    };
    Matrix POW(Matrix m,ll k){
        Matrix ans;
        memset(ans.mat,0,sizeof(ans.mat));
        for(int i=0;i<size;i++) ans.mat[i][i]=1;
        while(k){
            if(k&1) ans=ans*m;
            k/=2;
            m=m*m;
        }
        return ans;
    }
    int main() {
        Matrix m;
        m.clear();
        m.mat[0][0]=3;m.mat[0][1]=-1;
        m.mat[1][0]=1;m.mat[1][1]=0;
        int T;
        cin>>T;
        for(int i=0;i<T;i++){
            cin>>n>>MOD;
            if(n==0) {cout<<0<<endl;continue;}
            Matrix ans=POW(m,n-1);
            ll sum=(ans.mat[0][0]%MOD+MOD)%MOD;
            cout<<sum<<endl;
        }   
        return 0;
    }
    View Code

     

  • 相关阅读:
    (OK) usbip-utils
    How To Set Up A USB-Over-IP Server And Client With Ubuntu 10.04
    linux内核模块获取设备IP地址
    (OK) 国内常用NTP服务器地址及IP
    2017年我国将开始部署和建设IPv6地址项目
    C++之STL和Boost
    linux内核IOCTL网络控制框架实现分析
    2016年 AI 技术发展综述
    2016年SDN/NFV开源三大趋势
    Angular
  • 原文地址:https://www.cnblogs.com/xiaowuga/p/7352261.html
Copyright © 2011-2022 走看看