届かない恋
宝宝容斥。下文记
先对序列排序。考虑求出
暴力容斥求出
观察
发现后面这个东西是关于
因为太丑,代码里把 ntt 板子去掉了。
#include <bits/stdc++.h>
#define LL long long
#define ull unsigned long long
#define uint unsigned int
using namespace std;
const int N = 1e6 + 10;
const ull MOD = 998244353;
ull Qpow(ull x, ull k, ull P) {
ull res = 1, tmp = x;
for (; k; k >>= 1, tmp = tmp * tmp % P) if (k & 1) res = res * tmp % P;
return res;
}
int n, m, S, A[N], tot, tmp[N];
ull fact[N], inv[N]; int lim = 1e6;
ull C(int n, int m) {
return (n < m ? 0 : fact[n] * inv[m] % MOD * inv[n - m] % MOD);
}
ull G[N], F[N];
namespace FNTT { /* NTT */ } using FNTT::NTT;
int main() {
freopen(".in", "r", stdin); freopen(".out", "w", stdout);
ios::sync_with_stdio(false); cin.tie(0), cout.tie(0);
fact[0] = 1;
for (int i = 1; i <= lim; i ++) fact[i] = fact[i - 1] * i % MOD;
inv[lim] = Qpow(fact[lim], MOD - 2, MOD);
for (int i = lim; i >= 1; i --) inv[i - 1] = inv[i] * i % MOD;
int _; cin >> _;
while (_ --) {
cin >> n >> m; S = n * m;
for (int i = 1; i <= S; i ++) cin >> A[i];
sort(A + 1, A + 1 + S);
for (int i = 1; i <= S; i ++) tmp[i] = A[i];
tot = unique(tmp + 1, tmp + 1 + S) - tmp - 1;
int len = 1; while (len <= (S << 1)) len <<= 1;
for (int i = 0; i < len; i ++) F[i] = G[i] = 0;
for (int i = 0; i < S; i ++) F[i] = 0, G[i] = inv[i];
for (int a = 0; a < n; a ++) for (int b = 0; b < m; b ++) {
int t = n * b + a * m - a * b;
ull tmp = inv[t] * fact[t] % MOD
* fact[S - t] % MOD * C(n, a) % MOD * C(m, b) % MOD;
if ((a + b) & 1) F[t] += MOD - tmp;
else F[t] += tmp;
}
for (int i = 0; i < len; i ++) F[i] %= MOD;
NTT(F, len, 1); NTT(G, len, 1);
for (int i = 0; i < len; i ++) F[i] = F[i] * G[i] % MOD;
NTT(F, len, -1);
ull Ans = fact[S] * tmp[1] % MOD;
for (int i = 1, c = 0; i < tot; i ++) {
while (c < S && A[c + 1] <= tmp[i]) ++ c;
ull res = fact[c] * F[c] % MOD;
Ans += res * (tmp[i + 1] - tmp[i]) % MOD;
}
cout << Ans % MOD << "\n";
}
return 0;
}