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 97 98
| #include <cstdio> #include <iostream> #include <bitset> #include <algorithm> #include <cstring> using namespace std;
const long long Mod = 998244353; int T, n, W, H, sx[25], sy[25], cntx, cnty, k;
long long inv[25], f[1 << 11];
bitset<500> mask[12], state, tmp;
struct Rect { pair<int, int> l, r; }rect[15];
inline long long qpow(long long a, long long b) { long long res = 1; while(b) { if(b & 1) res = res * a % Mod; a = a * a % Mod; b >>= 1; } return res; }
void dfs(int u, int s) { if(u == n + 1) { f[s] = state.count() == k ? 0 : -1; return ; } bitset<500> t = state; dfs(u + 1, s); state = t; state |= mask[u]; dfs(u + 1, s | (1 << (u - 1))); }
int main() { for(int i = 1; i <= 20; ++i) inv[i] = qpow(i, Mod - 2);; scanf("%d", &T); while(T--) { scanf("%d", &n); scanf("%d%d", &W, &H); cntx = cnty = 0; memset(f, 0, sizeof f); for(int i = 1; i <= n; ++i) { scanf("%d%d%d%d", &rect[i].l.first, &rect[i].l.second, &rect[i].r.first, &rect[i].r.second); rect[i].l.first = min(rect[i].l.first, W); rect[i].l.second = min(rect[i].l.second, H); rect[i].r.first = min(rect[i].r.first, W); rect[i].r.second = min(rect[i].r.second, H); sx[++cntx] = rect[i].l.first; sx[++cntx] = rect[i].r.first; sy[++cnty] = rect[i].l.second; sy[++cnty] = rect[i].r.second; } sort(sx + 1, sx + 1 + cntx); sort(sy + 1, sy + 1+ cnty); cntx = unique(sx + 1, sx + 1 + cntx) - (sx + 1); cnty = unique(sy + 1, sy + 1 + cnty) - (sy + 1); k = (cntx - 1) * (cnty - 1); for(int i = 1; i <= n; ++i) { rect[i].l.first = lower_bound(sx + 1, sx + 1 + cntx, rect[i].l.first) - sx; rect[i].l.second = lower_bound(sy + 1, sy + 1 + cnty, rect[i].l.second) - sy; rect[i].r.first = lower_bound(sx + 1, sx + 1 + cntx, rect[i].r.first) - sx; rect[i].r.second = lower_bound(sy + 1, sy + 1 + cnty, rect[i].r.second) - sy; mask[i].reset(); tmp.reset(); tmp = (1 << (rect[i].r.second - rect[i].l.second)) - 1; tmp <<= rect[i].l.second - 1; for(int j = rect[i].l.first - 1; j < rect[i].r.first - 1; ++j) mask[i] |= (tmp << (j * cnty)); } state.reset(); dfs(1, 0); if(f[(1 << n) - 1] == -1) { printf("-1\n"); continue; } for(int i = (1 << n) - 1; i >= 0; --i) { if(f[i] != -1) continue; int cnt = 0; long long res = 0; for(int j = 1; j <= n; ++j) { if((i >> (j - 1)) & 1) cnt++; else res = (res + 1LL * inv[n] * f[i | (1 << (j - 1))]) % Mod; } f[i] = (((1LL + res) * n) % Mod * inv[n - cnt]) % Mod; } printf("%lld\n", f[0]); } return 0; }
|