2020 Multi-University Training Contest 1 . Fibonacci Sum 水題改編


 

題意很簡單,就是讓你求這個東西,這個時候你發現,原題????

https://blog.csdn.net/acdreamers/article/details/23039571

哦,只是原來寫過的哪一題的C是1,這個是1e18. 想都不用想,直接二項式展開,求等比數列的前n項和。

你會得到第i項(一共k項):

這個時候理所當然的想先用二次剩余求出來那幾個用到的東西,a,b,1/sqrt(5)。

1你用快速冪求了一下,一交,tle了。

2 然后發現每個都求快速冪太蠢了,所以又優化優化,優化到除了求分母的逆元需要用到快速冪其他的都可以由上一項推出來,然后再交,又wa了。

3 哦,原來這是等比數列,分母是1-q,如果q是1那不就錯了嗎?所以特判一下如果q是1,加的就是n*a1,a1是幾?你看這個Sn,忽略這個組合數,a1不就和q完全相等嗎,是1! 就這樣a了。

#include <bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define met(a, b) memset(a, b, sizeof(a))
#define rep(i, a, b) for(int i = a; i <= b; i++)
#define bep(i, a, b) for(int i = a; i >= b; i--)
#define pb push_back
#define mp make_pair
#define debug cout << "KKK" << endl
#define ls num*2
#define rs num*2+1
#define re return
using namespace std;
const ll mod = 1e9 + 9;
const double PI = acos(-1);
const ll INF = 2e18+1;
const int inf = 1e9+5;
const double eps = 1e-7;
const int maxn = 1e5 + 5;
// 逆元
// sqrt(5) = 383008016;
// a = (1+sqrt(5))/2 = 691504013;
// b = (1-sqrt(5))/2 = 308495997;
// 1/sqrt(5) = 276601605;
ll A = 691504013, B = 308495997;
ll sqrt5 = 383008016, invsqrt5 = 276601605;
ll qsm(ll a, ll n){
    ll res = a%mod, sum = 1;
    while(n){
        if(n&1) sum = (sum*res)%mod;
        res = (res*res)%mod;
        n >>= 1;
    }
    return sum;
}

ll fac[maxn], f[maxn], inv[maxn];
ll C(ll m, ll n){
    if(m < n) return 0;
    if(n == 0 || m == n) return 1;
    return fac[m]*inv[n]%mod*inv[m-n]%mod;
}
void init(){
    fac[1] = 1; 
    f[1] = 1;   
    inv[1] = 1; 
    for(ll i = 2; i <= 100000; i++){
        fac[i] = fac[i-1]*i%mod;
        f[i] = (mod - mod/i)*f[mod%i]%mod;
        inv[i] = inv[i-1]*f[i]%mod;
    }
}

ll sac[maxn], sbc[maxn];
int main(){
    // ios::sync_with_stdio(false);
    // cin.tie(0); cout.tie(0);
    init();
    int t; scanf("%d", &t);
    while(t--){
        ll n, c, k; 
        scanf("%lld%lld%lld", &n,&c,&k);
        // n = 1e18, c = 1e18, k = 1e5;
        ll res = qsm(invsqrt5, k);
        ll ans = 0, flag = -1;
        ll x, y;
        ll ac = qsm(A, c), bc = qsm(B, c);
        sac[0] = 1, sbc[0] = 1;
        sac[1] = ac, sbc[1] = bc;
        rep(i, 1, k){
            sac[i] = sac[i-1]*ac%mod;
            sbc[i] = sbc[i-1]*bc%mod;
        }
        ll acn = qsm(qsm(A, c), n);
        ll bcn = qsm(qsm(B, c), n);
        ll invacn = qsm(acn, mod-2);
        ll invbcn = qsm(bcn, mod-2);
        ll now_acn = qsm(acn, k), now_bcn = 1;
        for(ll i = 0; i <= k; i++){
            flag *= -1;
            ll q = sac[k-i] * sbc[i] % mod;
            if(q == 1){
                q = (n%mod)*C(k, i) % mod;
                ans = (ans + flag*q%mod + mod) % mod; 
            }
            else{
                x = (C(k, i)*sac[k-i]%mod) * sbc[i] % mod;
                x = (1-(now_acn * now_bcn % mod) + mod) % mod * x % mod;
                y = (1 - (sac[k-i] * sbc[i])%mod ) % mod;
                y = qsm(y, mod-2);
                ans = (ans + flag*x*y%mod + mod)%mod;
            }
            now_acn = (now_acn * invacn) % mod;
            now_bcn = (now_bcn * bcn) % mod;
        }
        cout << ans*res%mod << endl;
    }
    return 0;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM