愚蠢的在线法官
给一个官解的简单理解,没有官解的严谨证明。
同官解,用 \(i\to j\) 表示 \(i\) 是 \(j\) 的祖先。
行列式的处理手法并不多,常规的手拆并不奏效,我们考虑化用 \(\gcd\) 矩阵的求法:定义矩阵 \(C[i][j]=[j\to A_i],D[i][j]=[i\to A_j](v_i-v_{fa_i})\),当 \(k=n\) 的时候 \(C,D\) 都是方阵,显然 \(B=C\times D\),于是 \(\det(B)=\det(C)\times \det(D)\),此时 \(C,D\) 的行列式是好求的,\(\mathcal O(n)\) 算就行。
然后考虑 \(k\neq n\),由 Cauchy-Binet 公式,\(|B|=\sum_{|S|=k} |C_{1\dots k, S}|\times |D_{S,1\dots k}|\)。
常见思路是考察 \(|C_{1\dots k,S}|\) 的组合意义,发现等价于给 \(A_1,\dots,A_k\) 各自钦定一个祖先,形成一个排列 \(\sigma\),累加贡献 \((-1)^{|\sigma|}\)。
对于这类行列式 / 其它的一些容斥问题,我们可以尝试通过构造去除一部分不好计算的贡献。具体的,如果 \(A_u,A_v\) 对应的匹配点可以交换,那么这些方案的系数全部会被抵消。称系数未被抵消的方案为合法方案。
考虑一个合法方案的生成,自底向上构造,我们发现任何一个时刻,不会有一个点的子树内有 \(>1\) 个未匹配点,于是对于给定的 \(S\),匹配的方案是唯一的,并且这样就抵消掉了 \((-1)^{|\sigma|}\) 这个烦人的东西。我们只需要把 \(v_i-v_{fa_i}\) 哪些东西的贡献算出来就好!
仍然考虑上述合法方案的生成方式,设 \(f_{u,0/1}\) 为 \(u\) 子树内还剩 \(0/1\) 个未匹配点的贡献和,转移就是子节点做一遍树上背包,然后分 \([u\in A]\) 是否为真进行讨论即可。时间复杂度 \(\mathcal O(n)\)。