Description
Solution
以下纯属口胡,并没有写。
考虑对于一个图,如果存在两个点使得它们不包含对方的连出点集不同,那么我交换两者的编号还是一个合法图,那么就会抵消掉,所以我们只需要考虑任意两个点不包含对方的连出点集都相同的情况。
对于连出点集相同的情况,如果两者没有连边,那么我选最大团一定只能选其中一个,否则我们可以两个都选。
所以我们可以考虑合并,我们设 \(s(u)\) 表示 \(u\) 表示的点集选出的最大团大小。那么上述情况中如果 \(u,v\) 存在边,那么 \(s(u)\to s(u)+s(v)\),否则 \(s(u)\to \max(s(u),s(v))\) ,然后将 \(u,v\) 合并。为了方便,\(u,v\) 没有边的时候只有 \(s(u)=s(v)\) 的时候我们才合并,可以看出一个点代表的点集连出子集都相同。
可以发现我们合并完的图,一定 \(s\) 都是 \(2^i\) 形式,且不会存在 \(s\) 相同的情况。因为如果存在相同的情况,二者连出点集一定相同,一定可以继续合并,否则贡献为 \(0\)。所以对于我们一个状态我们就可以用 \(b\in (0,n]\) 表示。
我们考虑设 \(f(n,b)\) 表示 \(n\) 个点的图缩成状态 \(b\) 的方案数,\(g(b,m)\) 表示状态为 \(b\) 的最大团刚好为 \(m\) 的方案数。
那么答案就是:
考虑如何求解 \(g(b,m)\) 的值,可以发现 \(g(b,m)=[m=b\vee m=b-\text{low}(b)]\)。
首先 \(m=b\vee m=b-\text{low}(b)]\) 一定有值。考虑其他情况,我们假设 \(y\) 是状态从大到小第一个没有选的,\(x\) 是选的最小值状态。因为 \(m\) 确定那么我们选的点就确定了。那么 \(y\) 是否与 \(x\) 相连都可以。因为如果 \(y\) 与其他点除 \(x\) 外都相连,那么我们选 \(y\) 一定最大团比 \(m\) 大,所以 \(y\) 一定不与其他点出 \(x\) 外都相连。
考虑我们如何求得 \(f(n,b)\) 的值。我们可以考虑在 \(n-1\) 个点的基础上加入一个点。你考虑合并过程,如果是一路合并没遇到 \(s\) 相同,那么会产生的 \(b\) 贡献就是 \(1\),那么就是 \(f(n-1,b-1)\),如果是一路合并然后 \(s\) 相同,那么一定是 \(\text{low}(b)\) 被合并到,贡献就是 \(f(n-1,b+\text{low}(b)-1)\)。
至此,我们得到了 \(\Theta(m\times (m+l))\) 的算法。
我们考虑使用生成函数进行优化 \(f\) 函数的计算。我们设 \(F_b(x)=\sum_{n} f(n,b)x^n\),那么我们可以得到 \(F_b(x)\) 的递推式。
而一方面我们可以看出:
其中 \(b_i\) 表示 \(b\) 二进制下第 \(i\) 位是否有值。
我们假设 \(G_k(x)=F_{2^k}(x)\),将两个式子合并以下可以得到: