[2020杭电多校第一场]1005 Fibonacci Sum(二次剩余 + 等比数列求和)

 

与此题几乎一样。(https://blog.csdn.net/acdreamers/article/details/23039571

不过注意,好像出题人赛后加强数据了,在枚举0-k的时候,里面最多只能有一个快速幂,其他的都尽量用变量迭代代替。要不然t飞。

#include<bits/stdc++.h>
#define ll long long
#define PB push_back
#define endl '\n'
#define INF 0x3f3f3f3f
#define LINF 0x3f3f3f3f3f3f3f3f
#define ull unsigned long long
#define lson rt << 1, l, mid
#define rson rt << 1 | 1, mid + 1, r
#define lowbit(x) (x & (-x))
#define rep(i, a, b) for(int i = a ; i <= b ; ++ i)
#define per(i, a, b) for(int i = b ; i >= a ; -- i)
#define clr(a, b) memset(a, b, sizeof(a))
#define in insert
#define random(x) (rand()%x)
#define PII(x, y) make_pair(x, y)
#define fi first
#define se second
#define pi acos(-1)
using namespace std;
const int maxn = 1e5 + 1000;
const ll mod = 1e9 + 9;
const ll gh5 = 383008016;
const ll inv5 = 276601605;
const ll ta = 691504013;
const ll tb = 308495997;
int T;
ll n, c, k;
ll fa[maxn], fb[maxn], fac[maxn], inv[maxn], inv_fac[maxn];
ll ksm(ll a, ll b){
    ll ans = 1, base = a % mod;
    while(b){
        if(b & 1) ans = ans * base % mod;
        base = base * base % mod;
        b >>= 1;
    }
    return ans;
}
ll C(ll n, ll m){
    if(n < m) return 0;
    if(n == m || m == 0) return 1;
    return fac[n] * inv_fac[m] % mod * inv_fac[n-m] % mod;
}
void init(){
    fac[1] = 1; inv[1] = 1; inv_fac[1] = 1;
    rep(i, 2, 100000){
        fac[i] = fac[i-1] * i % mod;
        inv[i] = (mod - (mod/i)) * inv[mod % i] % mod;
        inv_fac[i] = inv_fac[i-1] * inv[i] % mod;
    }
}
signed main(){
    cin >> T;
    init();
    while(T --){
        ll ans = 0, A, B;
        scanf("%lld %lld %lld", &n, &c, &k); fa[0] = fb[0] = 1;
        A = ksm(ta, c); B = ksm(tb, c);
        rep(i, 1, k) fa[i] = fa[i-1] * A % mod, fb[i] = fb[i-1] * B % mod;
        ll Fa = ksm(A, n);
        ll Fb = ksm(B, n);
        ll ia = ksm(Fa, mod-2);
        ll na = ksm(Fa, k), nb = 1;
        rep(r, 0, k){
            ll t = fa[k-r] * fb[r] % mod;
            ll tmp = 1;
            if(t == 1) tmp = C(k, r) * (n % mod) % mod;
            else tmp = C(k, r) * t % mod * (na * nb % mod - 1) % mod * ksm(t-1, mod-2) % mod;
            if(r & 1) ans = (ans - tmp + mod) % mod;
            else ans = (ans + tmp) % mod;
            na = na * ia % mod;
            nb = nb * Fb % mod;
        }
        ans = ans * ksm(inv5, k) % mod;
        cout << ans << endl;
    }
    return 0;
}
View Code

 

posted @ 2020-07-22 17:07  Ketchum  阅读(185)  评论(0编辑  收藏  举报