题解:AT_arc190_b [ARC190B] L Partition
记点的坐标为
考虑从大到小填,发现每次相当于构造出一个
考虑加上限制怎么做,发现这个点一定在一个
- 点在正方形的
4 个角上。
以下只考虑在其种一个角的情况,其余相同。
那么
- 点在正方形的
4 条边上。
以下只考虑在最上面的边的情况,其余相同。
跟上面的做法一样,容易得到
复杂度
#include <bits/stdc++.h>
#define int long long
#define rd read()
using namespace std;
inline int read() {
int x = 0; char ch = getchar();
while (ch < '0' || ch > '9') ch = getchar();
while (ch >= '0' && ch <= '9') x = (x << 1) + (x << 3) + (ch ^ 48), ch = getchar();
return x;
}
const int N = 1e7 + 5, mod = 998244353;
inline int qpow(int a, int b) {int res = 1; for (; b; b >>= 1, a = a * a % mod) if (b & 1) res = res * a % mod; return res;}
int n, a, b, fac[N], inv[N], f[N], q, pw[N], g[N], ans[N];
inline int C(int a, int b) {if (a < b || a < 0 || b < 0) return 0; return fac[a] * inv[b] % mod * inv[a - b] % mod;}
inline int solve(int x, int y, int k) {
if (x >= 1 && y >= 1 && x <= n && y <= n) return C(n - k, x - 1) * C(n - k, y - 1) % mod * 3 * pw[k - 2] % mod;
return 0;
}
signed main() {
n = rd, a = rd, b = rd, q = rd; fac[0] = pw[0] = 1;
for (int i = 1; i <= n; ++i) fac[i] = fac[i - 1] * i % mod, pw[i] = pw[i - 1] * 4 % mod;
inv[n] = qpow(fac[n], mod - 2); for (int i = n - 1; ~i; --i) inv[i] = inv[i + 1] * (i + 1) % mod;
int inv2 = qpow(2, mod - 2);
bool f1 = 0, f2 = 0;
for (int k = 1; k <= n; ++k) {
if (b - k + 1 <= b - 2 && !f1) {
for (int i = b - k + 1; i <= b - 2; ++i) f[k] = (f[k] + C(n - k, i)) % mod;
f1 = 1;
} else if (f1) f[k] = (f[k - 1] + C(n - k, b - k + 1) + C(n - k, b - 2)) * inv2 % mod;
if (a - k + 1 <= a - 2 && !f2) {
for (int i = a - k + 1; i <= a - 2; ++i) g[k] = (g[k] + C(n - k, i)) % mod;
f2 = 1;
} else if (f2) g[k] = (g[k - 1] + C(n - k, a - k + 1) + C(n - k, a - 2)) * inv2 % mod;
if (k == 1)ans[k] = C(n - k, a - 1) * C(n - k, b - 1) % mod;
else {
ans[k] = (ans[k] + solve(a, b, k)) % mod;
ans[k] = (ans[k] + solve(a - k + 1, b, k)) % mod;
ans[k] = (ans[k] + solve(a, b - k + 1, k)) % mod;
ans[k] = (ans[k] + solve(a - k + 1, b - k + 1, k)) % mod;
ans[k] = (ans[k] + C(n - k, a - 1) * f[k] % mod * 2 * pw[k - 2] % mod) % mod;
ans[k] = (ans[k] + C(n - k, a - k) * f[k] % mod * 2 * pw[k - 2] % mod) % mod;
ans[k] = (ans[k] + C(n - k, b - 1) * g[k] % mod * 2 * pw[k - 2] % mod) % mod;
ans[k] = (ans[k] + C(n - k, b - k) * g[k] % mod * 2 * pw[k - 2] % mod) % mod;
}
}
while (q--) cout << ans[rd] << '\n';
return 0;
}