任意模数下的积和式并没有多项式解法。考虑积和式的组合意义,i,Ai 都是互不相同的,可以看作是二分图的一个完美匹配。因此任意矩阵的积和式就是 Ax,y 看作左侧 x 右侧 y 之间的边权后所有完美匹配边权的积的和。
如果我们给所有 Ax,y≠1 拆成 1,Ax,y−1 这两个东西,然后所有边上都有了一个长度为 1 的边。于是现在就可以不考虑所有长度为 1 的边了。我们求出除开边权为 1 的边后的任意一个二分图匹配,那么这个匹配的贡献直接乘上未匹配点的个数的阶乘即可。因为剩下的点都可以任意匹配,而且一定可以通过 1 边匹配上。
但是这样点的数量还是 O(2k) 的。我们可以考虑对每个连通块分别计算,然后乘法原理乘起来即可。这样每个连通块内的点数就一定不超过 k 了。一种很容易想到的做法是对每个连通块做状压 dp ,考虑把点数较小的一边压成状态,然后枚举点数较多的一边来做 dp ,这样做一个点数为 n 边数为 m 的连通块的复杂度是 O((n2+m)2n2) 。这样是过不去的,如果卡满就是 50×225 。
考虑另外一种做法,求出这个二分图的一棵生成树,然后对于所有环边枚举环边的选取情况,然后在树上做一次背包来解决。这样做的复杂度是 O(2m−nn2) 。
我们选取其中较小的一种来做,复杂度是 O(min{m2n2,n22m−n}) 。在 n<23m 的时候用第一个做法,复杂度就是 O(n2213m) 。
于是最终复杂度就是 O(k2213k) ,而且非常不满。
cpp
1 |
|