求Fibonacci数列的幂次和([HDU6755]Fibonacci Sum)

在这里插入图片描述
对于 c = 1,有类似原题
原题链接

首先需要知道fibonacci的通项公式: f n = 1 5 ( ( 1 + 5 2 ) n ( 1 5 2 ) n ) f_n = \frac{1}{\sqrt5}*((\frac{1+\sqrt5}{2})^n-(\frac{1-\sqrt5}{2})^n) 这里简化成 f n = d ( a n b n ) f_n = d*(a^n-b^n)

然后对于原式子疯狂化简:
i = 0 n f i c k \sum_{i=0}^{n}f_{ic}^k
= i = 0 n ( d ( a n b n ) ) k =\sum_{i=0}^{n}(d*(a^n-b^n))^k
= d k i = 0 n ( a n b n ) k =d^k\sum_{i=0}^{n}(a^n-b^n)^k
然后二项式展开
= d k i = 0 k C k i ( 1 ) k i j = 0 n a i c j b i c ( k i ) =d^k*\sum_{i=0}^kC_k^i*(-1)^{k-i}\sum_{j=0}^{n}a^{icj}*b^{ic(k-i)}
然后后面一个是等比数列。

参考代码

#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
const int man = 2e5+10;
#define IOS ios::sync_with_stdio(0)
#define ull unsigned ll
#define uint unsigned
#define pai pair<int,int>
#define pal pair<ll,ll>
#define IT iterator
#define pb push_back
#define fi first
#define se second
#define For(i,j,k) for (int i=(int)(j);i<=(int)(k);++i)
#define Rep(i,j,k) for (int i=(int)(j);i>=(int)(k);--i)
#define endl '\n'
#define ll long long
const ll mod = 1e9+9;
ll genh = 383008016,inv2 = 500000005;
int inv[man],fac[man];
ll n,c,k;int tpn;
int quick_mod(int a,int b,int mod){
    int ans = 1;
    while(b){
        if(b&1)ans = 1ll * ans * a %mod;
        b>>=1;
        a = 1ll * a * a % mod;
    }
    return ans;
}

void init(int n){
    fac[0] = 1;
    for(int i = 1;i <= n;++i)fac[i] = 1ll*fac[i-1]*i%mod;
    inv[n] = quick_mod(fac[n],mod-2,mod);
    for(int i = n-1;i >= 0;--i)inv[i] = 1ll*inv[i+1]*(i+1)%mod;
   // cout <<inv[0] <<endl;
}

#define inv_a 691504013
#define inv_b 308495997
#define inv_5 276601605

int C(int j){
    int res = 1ll*fac[k]*inv[j]%mod*inv[k-j]%mod;
    return res;
}

void slove(){
    ll ans = 0;
    int A = quick_mod(inv_a,c,mod),B = quick_mod(inv_b,c,mod);
    int tpa = 1,tpb = quick_mod(B,k,mod);
    int b = quick_mod(B,mod-2,mod);
    for(int i = 0;i <= k;++i){
        int t = 1ll*tpa*tpb%mod;
        int tp = 1;
        if(t==1)tp = (n+1)%mod;
        else tp = 1ll*(quick_mod(t,(n+1)%(mod-1),mod)-1+mod)%mod*quick_mod((t-1+mod)%mod,mod-2,mod)%mod;
        if((k-i)&1)if(tp!=0)tp = mod-tp;
        tp = 1ll*tp * C(i) % mod;
        ans = (1ll*ans + tp)%mod;
        tpa = 1ll*tpa * A % mod;
        tpb = 1ll*tpb * b % mod;
    }
    ans = 1ll * ans * quick_mod(inv_5,k,mod) % mod;
    printf("%lld\n",ans);
}

signed main() {
    #ifndef ONLINE_JUDGE
        //freopen("in.txt", "r", stdin);
        //freopen("out.txt","w",stdout);
    #endif
   // cout << quick_mod(genh,mod-2,mod)<< endl;
    int t;scanf("%d",&t);
    init(100000);
    while(t--){
        scanf("%lld%lld%lld",&n,&c,&k); 
        c %= (mod-1);
        tpn = n%(mod-1);
        slove();
    }
    return 0;
}

/*
1
1000000000000000000 1000000000000000000 100000
*/

猜你喜欢

转载自blog.csdn.net/weixin_43571920/article/details/107516524
今日推荐