Fibonacci Sum

Fibonacci Sum

利用斐波那契通项求和,并二项式展开即可。其中求斐波那契需要用到二次剩余求根号5的值。

// Created by CAD
#include <bits/stdc++.h>
#define ll long long
using namespace std;

const int mod=1e9+9;
ll five=383008016;
inline int qpow(int x,int n){
    ll ans=1;
    while(n>0){
        if(n&1) ans=ans*x%mod;
        n>>=1,x=1ll*x*x%mod;
    }
    return ans;
}
const int maxn=1e5+5;
ll fac[maxn],inv[maxn];
void init()
{
    fac[0]=1;
    for(int i=1;i<maxn;i++)
        fac[i]=(fac[i-1])*i%mod;
    inv[maxn-1]=qpow(fac[maxn-1],mod-2);
    inv[0]=1;
    for(int i=maxn-2;i>=1;--i)
        inv[i]=inv[i+1]*(i+1)%mod;
}
int C(int n,int k)
{
    return fac[n]*inv[k]%mod*inv[n-k]%mod;
}
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    int T;cin>>T;
    init();
    int A=(five+1)*qpow(2,mod-2)%mod;
    int B=((1-five)*qpow(2,mod-2)%mod+mod)%mod,_B=qpow(B,mod-2);
    int _five=qpow(five,mod-2);

    while(T--){
        ll n,c,k;cin>>n>>c>>k;
        int _five_k=qpow(_five,k);
        c%=(mod-1);
        int ans=0;
        int Ac=qpow(A,c),Bc=qpow(B,c);
        int q=qpow(Ac,k);
        int _Ac=qpow(Ac,mod-2);
        int _AcBc=qpow(1ll*_Ac*Bc%mod,(n+1)%(mod-1));
        int up_left=qpow(q,(n+1)%(mod-1));
        for(int r=0;r<=k;++r){
            int cur=C(k,r);
            if(r&1) cur=mod-cur;
            if(q==1) ans=(1ll*ans+(n)%mod*cur%mod)%mod;
            else
                ans=(1ll*ans+(1ll*up_left-q)%mod*qpow(q-1,mod-2)%mod*cur)%mod;
            q=1ll*q*_Ac%mod*Bc%mod;
            up_left=1ll*up_left*_AcBc%mod;
        }
        cout<<(1ll*ans*_five_k%mod+mod)%mod<<endl;
    }
    return 0;
}
posted @ 2020-07-29 10:33  caoanda  阅读(161)  评论(0编辑  收藏  举报