Team work UOJ449 [2018] feeding pigeons

The meaning of problems

Z is small pigeons people. One day, the small Z to feed pigeons eat corn. A total of \ (n \) the probability of pigeons and other small Z will select a second and give him a pigeon corn. A dove full if and only if it ate the number of corn kernels \ (≧ K \) . Small Z wants you to tell him, expect the number of seconds after all the pigeons are full.

Data range: \ (n ≦ 50, k≤1000 \) , the answer mode \ (998,244,353 \) output

answer

Min-max is clearly very suitable for inclusion and exclusion order. \ (F (n-) \) as having \ (n-\) pigeons, in which a desired number of times to eat the feed, is obtained:

\[ ans = \sum_{i = 0} ^ {n} (-1) ^ {i + 1} \dbinom{n}{i} \frac{n}{i} f(i) \]

Multiplied by \ (\ frac {n} { i} \) it is desirable because feeding \ (\ frac {n} { i} \) times to have once fed to \ (i \) pigeons in a .

Vigorously to calculate \ (F (n-) \) , is assumed to be the first bird feed, fed a total of \ (j + k \) th, \ (j + k \) the feeding of times \ (1 \) only the feed. \ (G (n-, C) \) represents \ (n-\) pigeons, fed \ (C \) pieces of maize, a number of programs are not fed, because \ (n \) pigeons are likely to be fed and, finally, multiplied by \ (n \) :

\[ f(n) = n\sum_{j} \frac{(j + k)\dbinom{j+k-1}{j}g(n-1,j)}{n^{j+k}} \]

And \ (g (n, c) \) can be obtained by the EGF:

\[ g(n,c) = ((\sum_{i = 0} ^ {k - 1} \frac{x^i}{i!}) ^ n [x^c]) c! \]

Order \ (G = \ sum_ {I} = 0 {K ^ -. 1} \ I ^ X FRAC {} {!} I \) , violence calculate its front \ (n-\) power can be in \ (O (nk ^ 2log (nk)) \) within the complexity of the solution to this problem.

But there is a more beautiful approach.

\ (e ^ x = \ sum_ {i = 0} ^ {\ infty} \ frac {x} {^ i i!} \) ,而\ ((e ^ x) = e ^ x \)

For \ (G \) , may be similarly obtained \ (g '= g - \ frac {x ^ {k - 1}} {(k -! 1)} \)

thereby

\[ \begin{split} (g^n)' &= g^{n - 1} g' \\ &= (g^{n-1}) (g - \frac{x^{k-1}}{(k-1)!}) \\ &= g^n - \frac{x^{k-1}}{(k-1)!} g^{n-1} \end{split} \]

Can be drawn from \ (g ^ n [x ^ n] \) and \ (g [{n-1 } x ^] ^ n \) the relationship between, \ (O (. 1) \) computing a, overall complexity \ (O (nk ^ 2) \)

#pragma GCC optimize("2,Ofast,inline")
#include<bits/stdc++.h>
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define LL long long
#define pii pair<int, int>
using namespace std;
const int N = 5e4 + 10;
const int mod = 998244353;
 
template <typename T> T read(T &x) {
    int f = 0;
    register char c = getchar();
    while (c > '9' || c < '0') f |= (c == '-'), c = getchar();
    for (x = 0; c >= '0' && c <= '9'; c = getchar())
        x = (x << 3) + (x << 1) + (c ^ 48);
    if (f) x = -x;
    return x;
}

namespace Comb {
    const int Maxn = 1e6 + 10;
    
    int fac[Maxn], fav[Maxn], inv[Maxn];
    
    void comb_init() {
        fac[0] = fav[0] = 1;
        inv[1] = fac[1] = fav[1] = 1;
        for (int i = 2; i < N; ++i) {
            fac[i] = 1LL * fac[i - 1] * i % mod;
            inv[i] = 1LL * -mod / i * inv[mod % i] % mod + mod;
            fav[i] = 1LL * fav[i - 1] * inv[i] % mod;
        }
    }
 
    inline int C(int x, int y) {
        if (x < y || y < 0) return 0;
        return 1LL * fac[x] * fav[y] % mod * fav[x - y] % mod;
    }

    inline int Qpow(int x, int p) {
        int ans = 1;
        for (; p; p >>= 1) {
            if (p & 1) ans = 1LL * ans * x % mod;
            x = 1LL * x * x % mod;
        }
        return ans;
    }

    inline int Inv(int x) {
        return Qpow(x, mod - 2);
    }
 
    inline void upd(int &x, int y) {
        (x += y) >= mod ? x -= mod : 0;
    }

    inline int add(int x, int y) {
        return (x += y) >= mod ? x - mod : x;
    }

    inline int dec(int x, int y) {
        return (x -= y) < 0 ? x + mod : x;
    }

}
using namespace Comb;

int n, k;
int f[51], g[51][N];
 
int main() {
    comb_init();
    read(n); read(k);
    g[0][0] = 1;
    for (int i = 0; i < k; ++i) {
        g[1][i] = fav[i];
    }
    for (int i = 2; i <= n; ++i) {
        g[i][0] = 1;
        for (int j = 1; j <= i * (k - 1); ++j) {
            g[i][j] = 1LL * i * g[i][j - 1] % mod;
            if (j >= k) g[i][j] = dec(g[i][j], 1LL * i * fav[k - 1] % mod * g[i - 1][j - k] % mod);
            g[i][j] = 1LL * g[i][j] * inv[j] % mod;
        }
    }
    int ans = 0;
    for (int i = 1; i <= n; ++i) {
        int pw = Qpow(inv[i], k);
        for (int j = 0; j <= (i - 1) * (k - 1); ++j) {
            int d = 1LL * (j + k) * C(j + k - 1, j) % mod * g[i - 1][j] % mod * fac[j] % mod * pw % mod;
            upd(f[i], 1LL * i * d % mod);
            pw = 1LL * pw * inv[i] % mod;
        }
        int del = 1LL * C(n, i) * n % mod * inv[i] % mod * f[i] % mod;
        if (!(i & 1)) del = mod - del;
        upd(ans, del);
    }
    cout << ans << endl;
    return 0;
}

Guess you like

Origin www.cnblogs.com/Vexoben/p/11728088.html