CF1716F Bags with Balls
题意
\(n\) 个盒子,每个盒子里有编号为 \(1 \to m\) 的 \(m\) 个球。
从每个盒子拿一个球,设取出的编号是奇数的球的数量为 \(F\).
求所有取球方案的 \(F ^ k\) 之和。
Sol
不难想到答案为:
\[\sum_{i = 0} ^ n \binom{n}{i} i ^ k (\lceil \frac{m}{2}\rceil) ^ i (\lfloor \frac{m}{2} \lfloor) ^ {n - i}
\]
套路地,将 \(i ^ k\) 转为下降幂。
\[\sum_{i = 0} ^ n \sum_{j = 0} ^ k \begin{Bmatrix} k \\ j\end{Bmatrix} i ^ {\underline j} \binom{n}{i} (\lceil \frac{m}{2} \rceil) ^ i (\lfloor \frac{m}{2} \lfloor) ^ {n - i}
\]
合并组合数和下降幂,调整求和顺序。
\[\sum_{j = 0} ^ k \begin{Bmatrix} k \\ j\end{Bmatrix} \sum_{i = 0} ^ n n ^ {\underline j} \binom{n - j}{i - j} (\lceil \frac{m}{2} \rceil) ^ i (\lfloor \frac{m}{2} \lfloor) ^ {n - i}
\]
后面这一坨很像二项式定理啊。
发现直接提个 \((\lceil \frac{m}{2} \rceil) ^ j\) 就能直接合并了。
\[\sum_{j = 0} ^ k \begin{Bmatrix} k \\ j \end{Bmatrix} (\lceil \frac{m}{2} \rceil) ^ j m ^ {n - j}
\]
直接计算即可。
Code
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <array>
#define int long long
using namespace std;
#ifdef ONLINE_JUDGE
#define getchar() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++)
char buf[1 << 23], *p1 = buf, *p2 = buf, ubuf[1 << 23], *u = ubuf;
#endif
int read() {
int p = 0, flg = 1;
char c = getchar();
while (c < '0' || c > '9') {
if (c == '-') flg = -1;
c = getchar();
}
while (c >= '0' && c <= '9') {
p = p * 10 + c - '0';
c = getchar();
}
return p * flg;
}
void write(int x) {
if (x < 0) {
x = -x;
putchar('-');
}
if (x > 9) {
write(x / 10);
}
putchar(x % 10 + '0');
}
const int N = 2e3 + 5, mod = 998244353;
int pow_(int x, int k, int p = mod) {
int ans = 1;
while (k) {
if (k & 1) ans = ans * x % p;
x = x * x % p;
k >>= 1;
}
return ans;
}
array <array <int, N>, N> f;
void Mod(int &x) {
if (x >= mod) x -= mod;
if (x < 0) x += mod;
}
signed main() {
f[0][0] = 1;
for (int i = 1; i <= 2000; i++)
for (int j = 1; j <= 2000; j++)
f[i][j] = f[i - 1][j - 1] + j * f[i - 1][j] % mod, Mod(f[i][j]);
int T = read();
while (T--) {
int n = read(), m = read(), k = read();
int ans = 0, tp = 1;
for (int j = 0; j <= min(k, n); j++) {
ans += tp * f[k][j] % mod * pow_((m + 1) / 2, j) % mod * pow_(m, n - j) % mod, Mod(ans);
tp = tp * (n - j) % mod;
}
write(ans), puts("");
}
return 0;
}