. LOJ3119 "CTS2019 | CTSC2019" cube binomial random inversion

Topic Portal

https://loj.ac/problem/3119

Now BZOJ administrator has not worked yet, CTS (C) 2019 and NOI2019 subject up to now not to pass up.

Sure enough, or LOJ good.

topic

Exactly \ (k \) a great number of very good demand, we transformed into binomial inversion.

Then becomes a given set of points \ (S \) , seeking Imperial \ (S \) of the program is the number of points of the maximum point. Can be found in \ (S \) in point because of the need to ensure that there is no one-dimensional coordinates of the same, so what is the point in the end is not important, useful only \ (| S | \) . So the question into the Imperial (k \) \ a number of points must be the maximum point of the program.

We can find a nature, if we put all the numbers from small to large maximum point of consideration, then every election finished and current digital surface-related points later, how the rest of the numbers on the point of actual arrangements on a \ ((n-1) \ times (m-1) \ times (l-1), k-1 \) sub-problem.

We need to elect \ (\ k) a handpicked by our point of arrangement , they should not have to meet the one-dimensional coordinates are the same, so it is obviously \ (\ binom nk \ binom mk \ binom lk (k! ) ^ 3 \) . As for why the arrangement is, he says, only small to large consideration, only to meet the above properties.

Then we need to be our elected \ (k \) points located on all sides of all positions, all positions of the remaining digital arrangements. The remaining \ (nml- (nk) (mk ) (lk) \) well arranged, starting with all the \ (nml \) numbers selected out of so many, and then arranged freely about enough. This is the \ (\ Binom NML {} {(NK) (MK) (LK)} ((NK) (MK) (LK))! \) .

The main difficulty lies in the elected \ (K \) number of points where the surface. We have \ (nmk - (nk) ( mk) (lk) \) a digital alternative. Because we are in ascending order, so the numbers on the last elected position should be the biggest. At the same time, it will take away \ ((nk + 1) ( mk + 1) (lk + 1) - (nk) (mk) (lk) \) a final vote for it when the child cube in the same plane and it figures. In this case, because it is the largest, so no matter what the election will not affect the selection of numbers the previous location. Thus it has \ (\ frac {(nml- ( nk) (mk) (lk) -1)!} {(Nml- (nk + 1) (mk + 1) (lk + 1) )!} \) selecting method.

Then after the election finished, the penultimate number on the position to be elected, the rest of the numbers should be the greatest. A total remaining number \ (nml- (n-k + 1) (m-k + 1) (l-k + 1) \) species, and then the same as before the last considered it.

Therefore selected to be \ (K \) Total number of dots arranged face digital scheme where
\ [\ prod_ {i = 1 } ^ k \ frac {(nml- (ni) (mi) (li) -1)!} {(nml- (
n-i + 1) (m-i + 1) (l-i + 1))!} \] can be found on the part of the factorial we can eliminate, so that
\ [(nml- (nk) (mk ) (lk) -1)! \ prod_ {i = 1} ^ {k-1} \ frac 1 {(nml- (n-i + 1) (m-i + 1 ) (l-i + 1)
)} \] Thus the above things are all together, and Imperial the \ (K \) points must be the maximum point of the program number
\ [\ binom nk \ binom mk \ binom lk (k!) ^ 3 \ binom {nml} {(nk) (mk) (lk)} ((nk) (mk) (lk))! (nml- (nk) (mk) (lk) -1)! \ prod_ {i = 1} ^ {k-1} \ frac 1 {(nml- (n-i + 1) (m-i + 1) (l-i + 1))} \]

\[ =\binom nk\binom mk\binom lk(k!)^3\frac{(nml)!}{((n-k)(m-k)(l-k))!(nml-(n-k)(m-k)(l-k))!}((n-k)(m-k)(l-k))!(nml-(n-k)(m-k)(l-k)-1)!\prod_{i=1}^{k-1} \frac 1{(nml-(n-i+1)(m-i+1)(l-i+1))} \]

\ [= \ Binom nk \ binom mk \ binom lk (k!) ^ 3 {(nml)!} \ Prod_ {i = 1} ^ {k} \ frac 1 {(nml- (n-i + 1) ( m-i + 1) (l
-i + 1))} \] order \ (f (k) \) equal to the above that Imperial the (K \) \ point must be the maximum point of the program number, \ (G (K) \) represents exactly \ (K \) several points program, then clearly
\ [f (k) = \
sum_ {i = k} ^ n \ binom ikg (i) \] so direct binomial inversion on it.

Because demand is expected, and finally remember to get rid of \ ((NML)! \) .


Here is the code. \ (\ prod \ limits_ {i = 1} ^ {k} \ frac 1 {(nml- (n-i + 1) (m-i + 1) (l-i + 1))} \) can be pre-linear process, so the total time complexity is \ (O (n-) \) .

#include<bits/stdc++.h>

#define fec(i, x, y) (int i = head[x], y = g[i].to; i; i = g[i].ne, y = g[i].to)
#define dbg(...) fprintf(stderr, __VA_ARGS__)
#define File(x) freopen(#x".in", "r", stdin), freopen(#x".out", "w", stdout)
#define fi first
#define se second
#define pb push_back

template<typename A, typename B> inline char smax(A &a, const B &b) {return a < b ? a = b , 1 : 0;}
template<typename A, typename B> inline char smin(A &a, const B &b) {return b < a ? a = b , 1 : 0;}

typedef long long ll; typedef unsigned long long ull; typedef std::pair<int, int> pii;

template<typename I>
inline void read(I &x) {
    int f = 0, c;
    while (!isdigit(c = getchar())) c == '-' ? f = 1 : 0;
    x = c & 15;
    while (isdigit(c = getchar())) x = (x << 1) + (x << 3) + (c & 15);
    f ? x = -x : 0;
}

const int N = 5e6 + 7;
const int P = 998244353;

int n, m, l, k;
int a[N], s[N], f[N];

inline int smod(int x) { return x >= P ? x - P : x; }
inline void sadd(int &x, const int &y) { x += y; x >= P ? x -= P : x; }
inline int fpow(int x, int y) {
    int ans = 1;
    for (; y; y >>= 1, x = (ll)x * x % P) if (y & 1) ans = (ll)ans * x % P;
    return ans;
}

int fac[N], inv[N], ifac[N];
inline void ycl(const int &n = ::n) {
    fac[0] = 1; for (int i = 1; i <= n; ++i) fac[i] = (ll)fac[i - 1] * i % P;
    inv[1] = 1; for (int i = 2; i <= n; ++i) inv[i] = (ll)(P - P / i) * inv[P % i] % P;
    ifac[0] = 1; for (int i = 1; i <= n; ++i) ifac[i] = (ll)ifac[i - 1] * inv[i] % P;
}

inline int C(int x, int y) {
    if (x < y) return 0;
    return (ll)fac[x] * ifac[y] % P * ifac[x - y] % P;
}

inline void work() {
    ycl(std::max(m, l));
    int nml = (ll)n * m % P * l % P, ii = 1;
    a[0] = 1;
    for (int i = 1; i <= n; ++i) a[i] = (nml + P - (ll)(n - i) * (m - i) % P * (l - i) % P) % P, ii = (ll)ii * a[i] % P;
    ii = fpow(ii, P - 2);
    for (int i = n; i; --i) s[i] = ii, ii = (ll)ii * a[i] % P;
    for (int i = 1; i <= n; ++i) f[i] = (ll)C(n, i) * C(m, i) % P * C(l, i) % P * fpow(fac[i], 3) % P * s[i] % P;
    int ans = 0;
    for (int i = k; i <= n; ++i)
        if ((i - k) & 1) sadd(ans, P - (ll)C(i, k) * f[i] % P);
        else sadd(ans, (ll)C(i, k) * f[i] % P);
    printf("%d\n", ans);
}

inline void init() {
    read(n), read(m), read(l), read(k);
    if (n > m) std::swap(n, m);
    if (n > l) std::swap(n, l);
}

int main() {
#ifdef hzhkk
    freopen("hkk.in", "r", stdin);
#endif
    int T;
    read(T);
    while (T--) {
        init();
        work();
    }
    fclose(stdin), fclose(stdout);
    return 0;
}

Guess you like

Origin www.cnblogs.com/hankeke/p/LOJ3119.html