杭电多校第一场 [Fibonacci Sum]

杭电多校第一场 Fibonacci Sum

题解:

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

按照这个博客可以推出式子,但是直接按照这个写会tle,所以要进行优化。

https://www.cnblogs.com/lonely-wind-/p/13364393.html

按照这个博客对快速幂进行优化即可。

看完之后建议自己从头到尾再手推一遍,加深印象。

先贴一下最开始的那份代码:

#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn = 1e5+10;
const int mod = 1e9+9;
ll fac[maxn],A[maxn],B[maxn];
void Init() {
    fac[0] = 1;
    for (int i = 1; i < maxn; i++)
        fac[i] = fac[i - 1] * i % mod;
    A[0] = B[0] = 1;
    for (int i = 1; i < maxn; i++) {
        A[i] = A[i - 1] * 691504013 % mod;
        B[i] = B[i - 1] * 308495997 % mod;
    }

}
long long binpow(long long x,long long k) {
    long long ans = 1;
    while (k) {
        if (k & 1) ans = ans * x % mod;
        x = x * x % mod;
        k >>= 1;
    }
    return ans;
}

int main() {
    int t;
    Init();
    scanf("%d", &t);
    ll f = 383008016;
    ll m = binpow(f, mod - 2);
    while (t--) {
        ll n, c, k, ans = 0;
        scanf("%lld%lld%lld", &n, &c, &k);
        ll ac = binpow(A[1], c), bc = binpow(B[1], c);
        for (int i = 0; i <= k; i++) {
            ll q = binpow(ac, k - i) * binpow(bc, i) % mod, tmp = (n + 1) % mod,C = fac[k] % mod * binpow(fac[i] * fac[k - i] % mod, mod - 2);
            if (q != 1) tmp = (binpow(q, n + 1) - 1 + mod) % mod * binpow(q - 1, mod - 2) % mod;
            ll res = tmp * C % mod;
            if (i & 1) ans = (ans - res + mod) % mod;
            else ans = (ans + res) % mod;
        }
        ans = ans * binpow(m, k) % mod;
        ans = (ans % mod + mod) % mod;
        printf("%lld\n", ans);
    }
}

AC代码

#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn = 1e5+10;
const int mod = 1e9+9;
inline ll read(){
    ll X=0; bool flag=1; char ch=getchar();
    while(ch<'0'||ch>'9') {if(ch=='-') flag=0; ch=getchar();}
    while(ch>='0'&&ch<='9') {X=(X<<1ll)+(X<<3ll)+ch-'0'; ch=getchar();}
    if(flag) return X;
    return ~(X-1);
}

long long binpow(long long x,long long k) {
    long long ans = 1;
    while (k) {
        if (k & 1) ans = ans * x % mod;
        x = x * x % mod;
        k >>= 1;
    }
    return ans;
}
ll fac[maxn],A[maxn],B[maxn],fac_inv[maxn];
void Init() {
    fac[0] = 1;
    for (int i = 1; i < maxn; i++)
        fac[i] = 1ll * fac[i - 1] * i % mod;
    A[0] = B[0] = 1;
    for (int i = 1; i < maxn; i++) {
        A[i] = 1ll * A[i - 1] * 691504013 % mod;
        B[i] = 1ll * B[i - 1] * 308495997 % mod;
    }
    fac_inv[1]=1,fac_inv[0]=1;
    for (int i=2; i<maxn; i++) fac_inv[i]=binpow(fac[i],mod-2);
}

int main() {
    Init();
    int t = read();
    ll m = binpow(383008016, mod - 2);
    while (t--) {
        ll n = read(), c = read(), k = read(), ans = 0;
        ll q = binpow(A[k], c) % mod;
        ll num = binpow(1ll * B[1] * binpow(A[1], mod - 2) % mod, c);
        ll qn = binpow(q, n) % mod;
        ll val = binpow(num, n) % mod;
        for (int i = 0; i <= k; i++) {
            ll C = 1ll * fac[k] * fac_inv[k - i] % mod * fac_inv[i] % mod;
            ll tmp = 1ll * q * (qn - 1 + mod) % mod * binpow(q - 1, mod - 2) % mod;
            if (q == 1) tmp = 1ll * n % mod;
            tmp = tmp * C % mod;
            if (i & 1) ans -= tmp;
            else ans += tmp;
            ans = (ans % mod + mod) % mod;
            q = 1ll * q * num % mod;
            qn = 1ll * qn * val % mod;
        }
        ans = ans * binpow(m, k) % mod;//!!!
        printf("%lld\n", ans);
    }
    return 0;
}


posted @ 2020-07-23 10:48  EchoZQN  阅读(119)  评论(0编辑  收藏  举报