1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
| #include <bits/stdc++.h>
const int kMaxN = 105, kMaxM = 5e3 + 35, kMaxK = 30, kMod = 1e9 + 7;
int n, m, k; int f[kMaxM][kMaxK][kMaxN], inv[kMaxM * 2], res[kMaxN];
int qpow(int bs, int64_t idx = kMod - 2) { int ret = 1; for (; idx; idx >>= 1, bs = (int64_t)bs * bs % kMod) if (idx & 1) ret = (int64_t)ret * bs % kMod; return ret; }
inline int add(int x, int y) { return (x + y >= kMod ? x + y - kMod : x + y); } inline int sub(int x, int y) { return (x >= y ? x - y : x - y + kMod); } inline void inc(int &x, int y) { (x += y) >= kMod ? x -= kMod : x; } inline void dec(int &x, int y) { (x -= y) < 0 ? x += kMod : x; }
void prework(int n = 10030) { for (int i = 1; i <= n; ++i) inv[i] = qpow(i); }
int getp(int x, int y) { return 1ll * x * inv[y] % kMod; }
void dickdreamer() { std::cin >> n >> m >> k; std::fill_n(res + 1, n, 0); for (int i = 0; i <= m; ++i) for (int j = 0; j <= k; ++j) std::fill_n(f[i][j], n + 1, 0); f[m][k][n] = 1; for (int i = m; i; --i) { for (int j = k; ~j; --j) { static int val[kMaxN], sum[kMaxN]; std::fill_n(val, n, 0); int coef = getp(i - 1, 2 * i + j - 2); if (!j) coef = (kMod + 1) / 2; for (int s = 0; s < std::min(n, i); ++s) inc(val[(s + 1) % n], 1ll * ((i - 1 - s) / n + 1) * coef % kMod * getp(1, i + j) % kMod); coef = 1ll * coef * getp(j, i + j) % kMod; for (int lst = 1; lst <= n; ++lst) { if (j) inc(f[i][j - 1][(lst + i - 1) % n + 1], 1ll * f[i][j][lst] * coef % kMod); } coef = getp(i + j - 1, 2 * i + j - 2); if (!j) coef = (kMod + 1) / 2; for (int s = 0; s < std::min(n, i + j); ++s) inc(val[(s + 1) % n], 1ll * ((i + j - 1 - s) / n + 1) * coef % kMod * getp(1, i + j) % kMod); for (int s = 1; s <= n; ++s) sum[s] = add(sum[s - 1], f[i][j][s]); std::function<int(int, int)> getsum = [&] (int l, int r) { if (l <= r) return sub(sum[r], sum[l - 1]); else return add(sum[r], sub(sum[n], sum[l - 1])); }; for (int l = 0, r = -1; l < n; l = r + 1) { for (; r + 1 < n && val[r + 1] == val[l]; ++r) {} for (int s = 1; s <= n; ++s) { inc(f[i - 1][j][s], 1ll * val[l] * getsum((s - r + n - 1) % n + 1, (s - l + n - 1) % n + 1) % kMod); inc(res[s], 1ll * val[l] * getsum((s - r + n - 1) % n + 1, (s - l + n - 1) % n + 1) % kMod); } } } } for (int i = 1; i <= n; ++i) std::cout << res[i] << " \n"[i == n]; }
int32_t main() { #ifdef ORZXKR freopen("in.txt", "r", stdin); freopen("out.txt", "w", stdout); #endif std::ios::sync_with_stdio(0), std::cin.tie(0), std::cout.tie(0); int T = 1; std::cin >> T; prework(); while (T--) dickdreamer(); return 0; }
|