首页 > 代码库 > HDU2855—Fibonacci Check-up

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

 

 

HDU2855—Fibonacci Check-up