像潮落潮涌,送我奔向自由。|

寂静的海底

园龄:3年2个月粉丝:59关注:15

2023-02-21 16:38阅读: 86评论: 0推荐: 0

【题解】带标号二分图计数

本文中 f[i] 表示 [xi]f(x)

带标号的二分图的数量不方便用一个式子直接写出,我们考虑用别的统计去推出它。

我们先求出连通二分图的生成函数,再求任意二分图的生成函数。

二分图想到黑白染色,二分图黑白染色的方案是好得到的:令 f(x) 表示所有 n 个点的图的的黑白染色方案之和的生成函数,则有

f[n]=i=0n(ni)×2i(ni)

稍微转化一下。

f[n]2n2/2×n!=i=0n1i!(ni)!×2i2/2×2(ni)2/2

就是加法卷积的形式了。

当一个二分图连通时,其黑白染色的方案等于 2,所以找到连通二分图的黑白染色的生成函数就形了。

连通图——任意图 是一种典型的“集合——集族”关系,它们的指数生成函数满足以下关系:

其中任意图的指数生成函数为 g(x),连通图的为 f(x)

Exp(f(x))=g(x)

做一次多项式 ln 再对每一项除二得到二分连通图的指数生成函数,再使用“集合——集族”关系 Exp 回去即可。

会发现上述过程等价于给 g(x) 开根,直接开根有更优秀的常数,时间复杂度都是 O(nlogn)

主要部分(因为我没想到对 2 的指数做一些很妙的转化,就直接用了二次剩余来处理除二的问题。其中 b2=2 ):

n=1e5;
rep(i,0,n) f[i] = math::finv[i] * math::Pow(b,(ll)i*i%(mod-1)*(mod-2)) % mod ;
poly::work(n+n);
poly::NTT(f);
poly::pmul(f,f,f);
poly::iNTT(f);
poly::mem(f+n+1,poly::L-n);
rep(i,0,n) f[i]=(ll)f[i] * math::Pow(b,(ll)i*i) % mod;
poly::ln(f,n,g);
poly::nummul(g,n,i2,g);
poly::exp(g,n,f);
rep(i,1,n) wrt(f[i] * math::fac[i] % mod,'\n');

完整代码

posted @   寂静的海底  阅读(86)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起