【题解】ABC273G Row Column Sums 2(感谢强大 alpha!!1【3】)
题意:求 \(n\times n\) 方阵个数,满足每列之和为 \(R_i\),每行之和为 \(C_i\) 。
数据范围:\(0\leq R_i,C_i\leq 2\),\(n\leq 10^7\) 。
转二分图,相当于限定左侧每个点和右侧每个点的度数。\(R,C=0\) 的行 / 列是无用的,去掉以后,我们认为还剩下 \(n\) 行 \(m\) 列。此时记录 \(r_1,r_2,c_1,c_2\) 分别表示度数为 \(1\) / \(2\) 的行 / 列个数(\(r_1+r_2=n\),\(c_1+c_2=m\)),判掉非法情况(\(r_1+2r_2\not=c_1+2c_2\))。
使用四元 EGF \(\begin{bmatrix}\frac{x^{r_1}y^{r_2}z^{c_1}w^{c_2}}{r_1!r_2!c_1!c_2!}\end{bmatrix}\) 计算:
- 环的 EGF:\(\frac{1}{2}\left(\ln \frac{1}{1-yw}-yw\right)\) 。
- 行 - 行 链的 EGF:\(\frac{1}{2}\frac{x^2w}{1-yw}\) 。
- 列 - 列 链的 EGF:\(\frac{1}{2}\frac{yz^2}{1-yw}\) 。
- 行 - 列 链的 EGF:\(\frac{xz}{1-yw}+\color{red}{yw}\)(注意到允许重边)。
即答案为:
然后换元:\(y\rightarrow st,w\rightarrow t^{-1},x\rightarrow uv,z\rightarrow v^{-1}\),再令 \(k=r_2-c_2\)(不失一般性地认为 \(k\geq 0\))有:
\(\frac{e^{s/2}}{\sqrt{1-s}}\) 是 D-finite 的,\(\frac{s^k}{2^k(1-s)^{k+r_1}}\) 也是 D-finite 的。而 \(F(s)=\sum\limits_{i\geq 0}\frac{s^i2^{-2i}}{i!(i+k)!(r_1-2i)!}\),发现 \([s^n]F(s)/[s^{n-1}]F(s)=\frac{(r_1-2n+2)(r_1-2n+1)}{4n(n+k)}\) 是关于 \(n\) 的有理分式,故 \(F(s)\) 是广义超几何函数,是 D-finite 的。即:
于是,在 \(r_1,k\) 是定值时,答案是关于 \(r_2\) 的整式递推。
\({}_pF_q\left(-\frac{r_1}{2},-\frac{r_1-1}{2};k+1;s\right)\) 可以直接算出每一项,我们只要解决 \(F=\frac{e^{s/2}\sqrt{1-s}}{(1-s)^{t}}\)(令 \(t=k+r_1+1\))。令 \(G=e^{s/2}\sqrt{1-s},H=\frac{1}{(1-s)^t}\),有 \(G'=\frac{1}{2}\frac{-sG}{1-s},H'=\frac{-tH}{1-s}\) 。于是有:
即 \((2-2s)F'=(2t-s)F\),初值是 \(F_0=1,F_1=t\),对比系数递推即可。
时间复杂度 \(O(n+\log p)\) 。
int Q, r1, r2, c1, c2, n, m, k, t, f[N];
signed main () {
init ();
IN (Q);
for (int r, i = 1; i <= Q; ++ i) if (IN (r), r) r == 1 ? ++ r1 : ++ r2;
for (int c, i = 1; i <= Q; ++ i) if (IN (c), c) c == 1 ? ++ c1 : ++ c2;
if (r1 + 2 * r2 != c1 + 2 * c2) return puts ("0"), 0;
if (r2 < c2) swap (r1, c1), swap (r2, c2);
n = r1 + r2, m = c1 + c2, k = r2 - c2, t = k + r1 + 1;
f[0] = 1, f[1] = t;
lep (i, 1, r2 - k - 1)
f[i + 1] = mul (mul (inv2, inv[i + 1]), dec (mul (2 * t + 2 * i, f[i]), f[i - 1]));
int ret = 0, buf = 1;
lep (i, 0, r2 - k) {
if (i * 2 > r1) break ;
int coef = mul (buf, mul (mul (ifac[i], ifac[i + k]), ifac[r1 - 2 * i]));
pls (ret, mul (f[r2 - k - i], coef)), buf = mul (buf, mul (inv2, inv2));
}
ret = mul (ret, qpow (2, mod - 1 - k));
ret = mul (ret, fac[r1]);
ret = mul (ret, fac[r2]);
ret = mul (ret, fac[c1]);
ret = mul (ret, fac[c2]);
printf ("%d\n", ret);
return 0;
}