CF1237F Balanced Domino Placements
阿新 • • 發佈:2020-11-16
CF1237F Balanced Domino Placements
題讀錯了。。。
對於一個骨牌的每個格子,不能有其他骨牌的格子和它在同一列或同一行。
那麼行列分開單獨考慮。
- 設 \(f_{i,j}\) 為前 \(i\) 行放了幾個佔了兩個格子的。
- 設 \(g_{i,j}\) 為前 \(i\) 列放了幾個佔了兩個格子的。
\(\begin{cases} f_{i,j} = f_{i-1,j} + f_{i-2,j-1} \cdot [2 \le i \&j \&!row_i\&!row_{i-1}] \\ g_{i,j} = g_{i-1,j} + g_{i-2, j-1} \cdot [2 \le i \&j\& !col_i \ \ \&!col_{i-1} \ \ ]\end{cases}\)
最後答案就是 \(f_{N,i} \cdot g_{M,j} \cdot C_{sumx - 2 \cdot i}^{j} \cdot C_{sumy - 2 \cdot j}^i \cdot i! \cdot j!\)
/* Name: 1237F Author: Gensokyo_Alice Date: 2020/11/16 Description: */ #include <algorithm> #include <iostream> #include <cstring> #include <cstdlib> #include <cstdio> #include <vector> #include <queue> #include <stack> #include <cmath> #include <ctime> #include <map> #include <set> using namespace std; typedef long long ll; const ll MAXN = 4e3+10, MOD = 998244353; ll N, M, K, col[MAXN], row[MAXN], sumx, sumy, fac[MAXN], inv[MAXN], ans, f[MAXN][MAXN], g[MAXN][MAXN]; ll P(ll, ll); int main() { scanf("%lld%lld%lld", &N, &M, &K); for (ll x, y, xx, yy, i = 1; i <= K; i++) { scanf("%lld%lld%lld%lld", &x, &y, &xx, &yy); col[y] = col[yy] = row[x] = row[xx] = 1; } inv[0] = inv[1] = fac[0] = fac[1] = 1; for (ll i = 2, k = MAXN - 10; i <= k; i++) inv[i] = inv[MOD % i] * (MOD - MOD / i) % MOD, fac[i] = fac[i-1] * i % MOD; for (ll i = 1, k = MAXN - 10; i <= k; i++) (inv[i] *= inv[i-1]) %= MOD; for (ll i = 1; i <= N; i++) sumx += !row[i]; for (ll i = 1; i <= M; i++) sumy += !col[i]; f[0][0] = g[0][0] = 1; for (ll i = 1; i <= N; i++) for (ll j = 0; 2 * j <= sumx; j++) f[i][j] = (f[i-1][j] + ((j && i >= 2 && !row[i] && !row[i-1]) ? f[i-2][j-1] : 0)) % MOD; for (ll i = 1; i <= M; i++) for (ll j = 0; 2 * j <= sumy; j++) g[i][j] = (g[i-1][j] + ((j && i >= 2 && !col[i] && !col[i-1]) ? g[i-2][j-1] : 0)) % MOD; for (ll i = 0; i * 2 <= sumx; i++) for (ll j = 0; j * 2 <= sumy; j++) (ans += f[N][i] * g[M][j] % MOD * P(j, sumx - 2 * i) % MOD * P(i, sumy - 2 * j) % MOD) %= MOD; printf("%lld", ans); return 0; } ll P(ll m, ll n) { if (m > n) return 0; return fac[n] * inv[n-m] % MOD; }