Combination count small practice

What combination of mathematics, the most interesting of it ......

[51nod 1251] Fox sequence number

The meaning of problems

The number of sequences required to meet the following conditions:

  1. Sequence of length $ n $, each element belonging to $ [1, m] \ cap Z $;
  2. This sequence did not fall monotonically;
  3. This number sequence occurs most often is unique.

Data range: $ 1≤n, m≤100000 $, the answer to $ 1e9 + 7 $ modulo

answer

To enumerate the highest number of occurrences of the number of $ k $ occurs, we have to calculate the $ x_1 + x_2 + ... + x_ {m-1} = nk,; the number of non-negative integer solution to x_i≤k-1 $ .

There can be enumerated by how many $ $ ≧ K, obviously need to enumerate the number does not exceed $ \ lfloor \ frac {n} {k} \ rfloor $, give the number of the allocated number $ k $ occurs, then the remaining number of random distribution, inclusion and exclusion just fine.

#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 = 200005;
const int mod = 1e9 + 7;

template <typename T> void read(T &x) {
    int f = 0;
    register char c = getchar();
    while (c < '0' || c > '9') f |= (c == '-'), c = getchar();
    for (x = 0; c >= '0' && c <= '9'; c = getchar())
        x = (x << 3) + (x << 1) + (c ^ '0');
    if (f) x = -x;
}

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

inline int sub(register int x, register int y) {
    return (x < y) ? (x - y + mod) : (x - y);
}

inline void upd(int &x, register int y) {
    static int z;
    x = ((z = x + y) >= mod) ? (z - mod) : z;
}

LL fac[N], fav[N], inv[N];

inline LL C(int x, int y) {
    if (x < y || y < 0) return 0;
    return fac[x] * fav[y] % mod * fav[x - y] % mod;
} 

void init() {
    fac[0] = fav[0] = 1;
    inv[1] = fac[1] = fav[1] = 1;
    for (int i = 2; i < N; ++i) {
        inv[i] = -mod / i * inv[mod % i] % mod + mod;
        fac[i] = fac[i - 1] * i % mod;
        fav[i] = fav[i - 1] * inv[i] % mod;
    }
}

void solve() {
    static int n, m, f[N];
    read(n); read(m);
    if (m == 1) return (void) (puts("1"));
    if (n == 1) return (void) (printf("%d\n", m));
    int ans = 0;
    for (int i = 1; i <= n; ++i) {
        upd(ans, m * C(n - i + m - 2, m - 2) % mod);
        for (int j = 1; j <= m - 1 && i * (j + 1) <= n; ++j) {
            int del = m * C(m - 1, j) % mod * C(n - i * (j + 1) + m - 2, m - 2) % mod;
            if (j & 1) upd(ans, mod - del);
            else upd(ans, del);
        }
    }
    cout << ans << endl;
}

int main() {
    init();
    int T; read(T);
    while (T--) solve();
    return 0;
}

[51nod 1634] FIG rigid

The meaning of problems

On a $ n * m $ grid of FIG was added (one in which two directions) in a plurality of diagonal lattice, the absence of such a method, all without changing the length of a side of the changing the shape of FIG.

Data range: $ n, m≤10 $

answer

It can be found in two small properties:

1, the two directions diagonal to the fixed plus side are equivalent in terms of FIG;

2, this figure is not a rigid body the following chart:

3, regardless of folding, in the same vertical line passing through the same column and a horizontal line must be parallel to each other.

Thus, addition of a diagonal line corresponding to a set of mandatory set of horizontal lines and a vertical line vertically.

Our goal is to make all horizontal and vertical lines vertical.

This is equivalent to n-Unicom $ $ $ X-point portion and $ m $ $ $ portion of the Y dots $ bipartite graph count.

The free and the DP as $ $ enough to communicate FIG.

#include<bits/stdc++.h>
using namespace std;
const int N = 11;
const int mod = 1e9 + 7;

int n, m;
int c[N][N], f[N][N];

inline void upd(int &x, register int y) {
    static int z;
    x = ((z = x + y) >= mod) ? (z - mod) : z;
}

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

int dfs(int n, int m) {
    if (~f[n][m]) return f[n][m];
    if (n == 0) return (m <= 1);
    if (m == 0) return (n <= 1);
    if (n == 1 && m == 1) return 2;
    int ans = Qpow(3, n * m);
    for (int i = 1; i <= n; ++i) {
        for (int j = 0; j <= m; ++j) {
            if (i + j == n + m) continue;
            int del = 1LL * dfs(i, j) * Qpow(3, (n - i) * (m - j)) % mod;
            del = 1LL * del * c[n - 1][i - 1] % mod;
            del = 1LL * del * c[m][j] % mod;
            upd(ans, mod - del);
        }
    }
    return f[n][m] = ans;
}

int main() {
    c[0][0] = 1;
    for (int i = 1; i < N; ++i) {
        c[i][0] = 1;
        for (int j = 1; j <= i; ++j) {
            c[i][j] = c[i - 1][j] + c[i - 1][j - 1];
        }
    }
    memset(f, 0xff, sizeof f);
    while (~scanf("%d%d", &n, &m)) printf("%d\n", dfs(n, m));
    return 0;
}

[51nod 1667] the probability of a good title

The meaning of problems

A and B compete.

They have $ k_1 $, $ k_2 $ sets $ [L_i, R_i] \ cap Z $

Every time a random number are taken from each set in their own

$ S_1 = \ sum $ A number fetched, $ S_2 $ empathy

If the $ S_1> S_2 $ Jiashengpan if $ S_1 = S_2 $ B win or draw

A separately obtained victory, a draw, the probability of B wins.

Data range: $ 1≤k_1, k_2≤8,1≤L≤R≤1e7 $

answer

A selected number is set $ R_i - x_i,; 0≤x_i≤R_i - L_i $, B is the number of the selected $ L_i + y_i,; 0≤y_i≤R_i - L_i $

A winning conditions so that $ \ sum R_i - x_i> \ sum L_i + y_i $, namely:

$ \sum x_i + y_i + k = \sum R_i - \sum L_i - 1 $

$ K $ a variable is introduced, so that we can into the equal sign equal sign. Apparently $ k ≥ 0 $

We have to calculate the stops this equation. Notes that the unknown does not exceed $ 17 $ months, we directly enumerates the number does not comply with the upper bound of inclusion and exclusion can be.

#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 = 1 << 20;
const int mod = 1e9 + 7;

template <typename T> void read(T &x) {
    int f = 0;
    register char c = getchar();
    while (c < '0' || c > '9') f |= (c == '-'), c = getchar();
    for (x = 0; c >= '0' && c <= '9'; c = getchar())
        x = (x << 3) + (x << 1) + (c ^ '0');
    if (f) x = -x;
}

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

inline int sub(register int x, register int y) {
    return (x < y) ? (x - y + mod) : (x - y);
}

inline void upd(int &x, register int y) {
    static int z;
    x = ((z = x + y) >= mod) ? (z - mod) : z;
}

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

int Inv(int x) {
    return Qpow(x, mod - 2);
}

LL fac[N], fav[N], inv[N], pw[N];

inline LL C(int x, int y) {
    if (x < y || y < 0) return 0;
    int ans = fav[y];
    for (int i = 0; i < y; ++i) {
        ans = 1LL * ans * (x - i) % mod;
    }
    return ans;
}

void init() {
    fac[0] = fav[0] = 1;
    inv[1] = fac[1] = fav[1] = 1;
    for (int i = 2; i < N; ++i) {
        inv[i] = -mod / i * inv[mod % i] % mod + mod;
        fac[i] = fac[i - 1] * i % mod;
        fav[i] = fav[i - 1] * inv[i] % mod;
    }
    pw[0] = 1;
    for (int i = 1; i < N; ++i) {
        pw[i] = pw[i - 1] * 2 % mod;
    }
}

int n, m, tot, k1, k2;
int lim[N], a[N];
int l1[N], r1[N], l2[N], r2[N], bitcnt[N];

int calc() {
    int ans = 0;
    for (int i = 0; i < (1 << m - 1); ++i) {
        bitcnt[i] = bitcnt[i >> 1] + (i & 1);
        int sum = 0;
        for (int j = 1; j < m; ++j) {
            if (i >> (j - 1) & 1) {
                sum += lim[j] + 1;
            }
        }
        int del = C(n - sum + m - 1, m - 1);
        if (bitcnt[i] & 1) upd(ans, mod - del);
        else upd(ans, del);
    }
    return ans;
}

void solve() {
    m = n = 0;
    tot = 1;
    read(k1);
    for (int i = 1; i <= k1; ++i) {
        read(l1[i]);
        read(r1[i]);
        lim[++m] = r1[i] - l1[i];
        tot = 1LL * tot * (r1[i] - l1[i] + 1) % mod;
        n += r1[i];
    }
    read(k2);
    for (int i = 1; i <= k2; ++i) {
        read(l2[i]);
        read(r2[i]);
        lim[++m] = r2[i] - l2[i];
        tot = 1LL * tot * (r2[i] - l2[i] + 1) % mod;
        n -= l2[i];
    }
    ++m; --n;
    LL s1 = calc();
    n = 0;
    for (int i = 1; i <= k1; ++i) {
        n -= l1[i];
    }
    for (int i = 1; i <= k2; ++i) {
        n += r2[i];
    }
    --n;
    LL s2 = calc();
    LL s3 = sub(tot, add(s1, s2));
    LL inv = Inv(tot);
    printf("%lld %lld %lld\n", s1 * inv % mod, s3 * inv % mod, s2 * inv % mod);
}

int main() {
    init();
    int T;
    read(T);
    while (T--) solve();
    return 0;
}

[codeforces 724F] Uniformly Branched Trees

The meaning of problems

Seeking pairwise disjoint configuration of a n-$ $ points unlabeled unrooted trees number, satisfying all non-leaf nodes of degree $ D $

Data range: $ n≤1000, d≤10 $

answer

A tree up to no more than two center of gravity. If we force of gravity of the tree is the root, the problem may be transformed into a rooted tree with the structure of the problem.

A first processing $ f_ {i, j, k} $ I $ denotes a size of $ rooted tree, the root of J is $ $, whose subtrees (not counting itself) the maximum size does not exceed $ k $, and the program number satisfying degree of internal node limit.

There are two transfer. One is not selected size $ k $ subtree, contribution $ f_ {i, j, k - 1} $, $ L ≧ 1 second is selection of size $ $ k $ subtree. Can be selected subtree $ f_ {k, d-1, k-1} $ species total to choose $ L $ trees, contribution was $ f_ {i-kl, jl, k-1} * \ binom {f_ {k, d-1, k-1} + l - 1} {f_ {k, d-1, k-1} -1} $, noted later that the number of combinations is equal to $ \ binom {f_ {k, d -1, k-1 + l - 1}} {l} $, this number may then be calculated in combination $ O (d) $ time. Need special sentence that, when $ k = 1 $ when they were added to the degree that point can be $ 0 $ (directly connected to a leaf).

If the n-$ $ is odd, the center of gravity and that there can be only one answer is $ f_ {n, d, \ lceil \ frac {n} {2} \ rceil -1} $

If the n-$ $ is an even number, the center of gravity may also have two. Obviously these two should be adjacent. Deleting attached between the two sides of the center of gravity, to obtain two sizes $ \ frac {n} {2} $ tree, the contribution is $ \ dbinom {f _ {\ frac {n} {2}, d- 1, \ frac {n} {2} -1} +1} {2} $

There is a special sentenced to $ n = 1 $, this is the only case of degree $ 0 $ allows point appears.

#include<bits/stdc++.h>
using namespace std;
const int N = 1005;

int n, d, mod;
int inv[N], fav[N], fac[N];
int f[N][11][N];

inline void upd(int &x, register int y) {
    static int z;
    x = ((z = x + y) >= mod) ? (z - mod) : z;
}

int C(int x, int y) {
    if (x < y || y < 0) return 0;
    int ans = 1;
    for (int i = 0; i < y; ++i) {
        ans = 1LL * ans * (x - i) % mod;
    }
    return 1LL * ans * fav[y] % mod;
}

int main() {
    cin >> n >> d >> mod;
    if (n == 1) return 0 * puts("1");
    fac[0] = fav[0] = 1;
    inv[1] = fac[1] = fav[1] = 1;
    for (int i = 2; i < N; ++i) {
        inv[i] = 1LL * -mod / i * inv[mod % i] % mod + mod;
        fac[i] = 1LL * fac[i - 1] * i % mod;
        fav[i] = 1LL * fav[i - 1] * inv[i] % mod;
    }
    for (int i = 0; i <= n; ++i) {
        f[1][0][i] = 1;
        f[1][d - 1][i] = 1;
    }
    for (int i = 2; i <= n; ++i) {
        for (int j = 1; j <= d; ++j) {
            for (int k = 1; k < i; ++k) {
                upd(f[i][j][k], f[i][j][k - 1]);
                for (int l = 1; l <= j && k * l  + 1 <= i; ++l) {
                    int del = f[i - k * l][j - l][min(k - 1, i - k * l - 1)];
                    del = 1LL * del * C(f[k][d - 1][k - 1] + l - 1, l) % mod;
                    upd(f[i][j][k], del);
                }
            }
        }
    }
    int ans = f[n][d][(n + 1) / 2 - 1];
    if (n % 2 == 0) {
        upd(ans, C(f[n / 2][d - 1][n / 2 - 1] + 1, 2));
    }
    cout << ans << endl;
    return 0;
}

[codeforces 960G] Bandit Blues

The meaning of problems

There $ $ n-backpack in a row, their values ​​are set exactly $ {1,2, ... n} $. A person picking up his backpack this way: a hand holding a start value $ 0 $ backpack, from left to right or from right to left to go, if you go to the location of the backpack value is greater than the value of his hands backpack, he use it to replace the hands of the backpack. This person is known to go from left to right will change $ A $ times backpack, walking from right to left will change $ B $ times backpack, and asked the number of possible permutations.

Data range: $ a, b, n≤200000 $, $ 998,244,353 $ answer mode output.

answer

A $ DP $ is obvious: Let $ f_ {i, j, k} $ represents the value of $ i $ Before considering a large backpack, from the left to go want to change $ j $ times, away from the right of the incumbent, $ k $ times number of permutations.

The first is to consider transferring large $ i $ that are added to the where. There are three cases. On the left: a plus that the $ J $; on the far right: make a $ k $ plus; in the middle of $ i-2 $ positions, $ j $ and $ k $ are unchanged.

This is $ O (n ^ 3) $ in consideration optimize this $ DP $.

The first optimization: notes placed on the far left and far right multiplication coefficient is the same, as a direct transfer to them as one kind, then the final answer multiplied by a $ \ dbinom {a + b} { a} $. I.e. with $ f_ {i, j} $ represents $ I $ considered before large numbers, a transfer and the transfer of a total of two aligned $ $ j number of times. This resulted in a $ O (n ^ 2) $ a $ DP $.

Second optimization: The transfer equation is now listed: $ f_ {i, j} = (i-2) * f_ {i-1, j} + f_ {i - 1, j - 1} $, if $ f_i $ regarded as a polynomial on $ j $, then multiplied by the transfer of the equivalent of a $ (i-2) + j $, so we just need to find the partition of $ FFT $ $ (0 + x) (1 + x) ... (n-2 + x) $ and the initial state about the merger get the answer. This can be done $ O (nlogn) $, but my code to achieve is $ O (nlog ^ 2n) $

#include<bits/stdc++.h>
#define LL long long
#define pb push_back
using namespace std;
const int G = 3;
const int N = 1 << 20;
const int mod = 998244353;

int n, a, b;
int rev[N];
int fac[N], fav[N], inv[N];

inline void upd(int &x, register int y) {
    static int z;
    x = ((z = x + y) >= mod) ? (z - mod) : z;
}

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

int C(int x, int y) {
    return 1LL * fac[x] * fav[y] % mod * fav[x - y] % mod;
}

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

int Inv(int x) {
    return Qpow(x, mod - 2);
}

void calrev(int lim, int l) {
    for (int i = 0; i < lim; ++i) {
        rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << l - 1);
    }
}

void NTT(int *a, int lim, int type) {
    for (int i = 0; i < lim; ++i) {
        if (i < rev[i]) swap(a[i], a[rev[i]]);
    }
    for (int len = 2; len <= lim; len <<= 1) {
        int Wn = Qpow(G, (mod - 1) / len), mid = len >> 1;
        for (int i = 0; i < lim; i += len) {
            int W = 1;
            for (int j = 0; j < mid; ++j) {
                int x = a[i + j], y = 1LL * a[i + j + mid] * W % mod;
                a[i + j] = add(x, y);
                a[i + j + mid] = add(x, mod - y);
                W = 1LL * W * Wn % mod;
            }
        }
    }
    if (type == -1) {
        reverse(a + 1, a + lim);
        int tmp = Inv(lim);
        for (int i = 0; i < lim; ++i) {
            a[i] = 1LL * a[i] * tmp % mod;
        }
    }
}

vector<int> mul(vector<int> a, vector<int> b) {
    int n = a.size() - 1, m = b.size() - 1;
    static int A[N], B[N];
    for (int i = 0; i <= n; ++i) A[i] = a[i];
    for (int i = 0; i <= m; ++i) B[i] = b[i];
    int lim = 1, l = 0;
    while (lim <= n + m + 2) {
        lim <<= 1;
        ++l;
    }
    for (int i = n + 1; i < lim; ++i) A[i] = 0;
    for (int i = m + 1; i < lim; ++i) B[i] = 0;
    calrev(lim, l);
    NTT(A, lim, 1);
    NTT(B, lim, 1);
    for (int i = 0; i < lim; ++i) {
        A[i] = 1LL * A[i] * B[i] % mod;
    }
    NTT(A, lim, -1);
    vector<int> ans;
    for (int i = 0; i <= n + m; ++i) {
        ans.pb(A[i]);
    }
    return ans;
}

vector<int> solve(int l, int r) {
    vector<int> ans;
    if (l == r) {
        ans.pb(l);
        ans.pb(1);
        return ans;
    }
    int mid = (l + r) >> 1;
    ans = mul(solve(l, mid), solve(mid + 1, r));
    return ans;
}

int main() {
    int n, a, b;
    cin >> n >> a >> b;
    if (n == 1) {
        if (a == 1 && b == 1) puts("1");
        else puts("0");
        return 0;
    }
    if (a == 0 || b == 0) return 0 * puts("0");
    vector<int> res = solve(0, n - 2);
    vector<int> tmp;
    tmp.pb(0); tmp.pb(0); tmp.pb(1);
    res = mul(res, tmp);
    fac[0] = fav[0] = 1;
    inv[1] = fac[1] = fav[1] = 1;
    for (int i = 2; i < N; ++i) {
        inv[i] = 1LL * -mod / i * inv[mod % i] % mod + mod;
        fac[i] = 1LL * fac[i - 1] * i % mod;
        fav[i] = 1LL * fav[i - 1] * inv[i] % mod;
    }
    if (res.size() < a + b + 1) return 0 * puts("0");
    cout << 1LL * C(a + b - 2, a - 1) * res[a + b] % mod << endl;
    return 0;
}

[JLOI2016] bests Comparison

The meaning of problems

Total $ $ G series n-bits students, $ M $ required course. This $ $ N is an integer number of bits students $ 0 to $ $ N-1 $, the number of God wherein B is $ 0 $ number. $ M $ required course this number is $ 0 to $ $ M-1 $ integer. A student can get in on the compulsory score is an integer from $ 1 $ to $ U_i $ in. If the results obtained for each course A is less than B equal results obtained, then A B is rolling. In God's statement in B, G Department a total of $ K $ classmate he rolled (not including himself), while the other $ NK-1 $ classmate if he was not rolling. D God, God found a B ranking for each required course. Here is the ranking: if a course is ranked as the God of B $ R $, it means that there is only $ R-1 $ bit in this course students score B score is greater than God, and only $ NR $ bit this course students score less than or equal B God (not including himself). We need to find the number of cases each required course for all students score the whole system so that it can meet the B God saying, God can be found in line D rankings. Here different if and only if there are any students get a different score on any one course in both cases. You do not like D God so powerful, you just need to figure out when the number of mold $ 10 ^ 9 + 7 $ remainder of it.

Data range: $ n, m≤100, u_i≤10 ^ 9,1≤r_i≤n $

answer

Provided $ f_ {i, j} $ $ I $ is considered the front course, there are several individual programs $ $ J crushed, then we have:

$ f_{i,j} = \sum_{k=j}^{n - 1} f_{i-1,k} \dbinom{k}{j} \dbinom{n-k - 1}{r_i - 1 - k + j} \sum_{l=1}^{u_i} l^{n-r_i}(u_i - l) ^ {r_i - 1} $

We may assume $ g (x) = \ sum_ {i = 1} ^ {x} i ^ {nr} (x - i) ^ {r_i - 1} $. Manual binomial expansion, you will find this is about $ x $ of $ n $ polynomial (note that $ \ sum $ will rise a number of times), directly on the Lagrange interpolation on OK

#include<bits/stdc++.h>
#define LL long long
#define pb push_back
using namespace std;
const int G = 3;
const int N = 205;
const int mod = 1e9 + 7;

int n, m, k;
int fac[N], fav[N], inv[N];
int u[N], r[N], f[N][N];

inline void upd(int &x, register int y) {
    static int z;
    x = ((z = x + y) >= mod) ? (z - mod) : z;
}

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

int C(int x, int y) {
    if (x < y || y < 0) return 0;
    return 1LL * fac[x] * fav[y] % mod * fav[x - y] % mod;
}

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

int Inv(int x) {
    return Qpow(x, mod - 2);
}

void prework() {
    scanf("%d%d%d", &n, &m, &k);
    for (int i = 1; i <= m; ++i) {
        scanf("%d", &u[i]);
    }
    for (int i = 1; i <= m; ++i) {
        scanf("%d", &r[i]);
    }
    fac[0] = fav[0] = 1;
    inv[1] = fac[1] = fav[1] = 1;
    for (int i = 2; i < N; ++i) {
        inv[i] = 1LL * -mod / i * inv[mod % i] % mod + mod;
        fac[i] = 1LL * fac[i - 1] * i % mod;
        fav[i] = 1LL * fav[i - 1] * inv[i] % mod;
    }
}

int calc(int x, int r) {
    static int y[N];
    for (int i = 0; i <= n; ++i) {
        y[i] = 0;
        for (int j = 0; j <= i; ++j) {
            upd(y[i], 1LL * Qpow(j, n - r) * Qpow(i - j, r - 1) % mod);
        }
    }
    int ans = 0;
    for (int i = 0; i <= n; ++i) {
        int tmp = 1;
        for (int j = 0; j <= n; ++j) {
            if (i == j) continue;
            tmp = 1LL * tmp * (x - j) % mod;
            tmp = 1LL * tmp * Inv(i - j) % mod;
        }
        if (tmp < 0) tmp += mod;
        upd(ans, 1LL * tmp * y[i] % mod);
    }
    return ans; 
}

void solve() {
    f[0][n - 1] = 1;
    for (int i = 1; i <= m; ++i) {
        int t = calc(u[i], r[i]);
        for (int j = 0; j <= n; ++j) {
            for (int k = j; k <= n; ++k) {
                int del = f[i - 1][k];
                del = 1LL * del * C(k, j) % mod;
                del = 1LL * del * C(n - k - 1, r[i] - 1 - k + j) % mod;
                upd(f[i][j], del);
            }
            f[i][j] = 1LL * f[i][j] * t % mod;
        }
    }
    printf("%d\n", f[m][k]);
}

int main() {
    prework();
    solve();
    return 0;
}

Guess you like

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