有标号DAG计数(生成函数)
有标号DAG计数(生成函数)
题解时间
首先考虑暴力,很容易得出 $ f[ i ] = \sum\limits_{ j = 1 }^{ i } ( -1 )^{ j - 1 } \binom{ i }{ j } 2^{ j( i - j ) } f[ i-j ] $ 。
相当于枚举度数为0的节点的个数,向不在这个集合里的点任意连边,之后需要容斥。
考虑如何优化。
$ j(i-j) = \frac{ i^{ 2 } }{ 2 } - \frac{ j^{ 2 } }{ 2 } - \frac{ ( i - j )^{ 2 } }{ 2 } $ 。
$ f[ i ] = \sum\limits_{ j = 1 }^{ i } ( -1 )^{ j - 1 } \frac{ i! }{ j!(i-j)! } \frac{ ( \sqrt{ 2 } )^{ i^{ 2 } } }{ ( \sqrt{ 2 } )^{ j^{ 2 } } ( \sqrt{ 2 } )^{ (i-j)^{ 2 } } } f[ i-j ] $ 。
构造 $ F(x) = \sum\limits_{ i = 0 }^{n} \frac{ f_{ i } }{ i! \sqrt{ 2 }^{ i^{ 2 } } } x^{ i } , G(x) = \sum\limits_{ i = 0 }^{n} \frac{ (-1)^{ i - 1 } }{ i! \sqrt{ 2 }^{ i^{ 2 } } } x^{ i } $ ,
有 $ F( x ) = F( x )G( x ) + 1 $ ,直接求逆。
如果要求图必须是弱连通呢?
直接对EGF取ln就好。
代码
#include<bits/stdc++.h>
using namespace std;
typedef long long lint;
namespace RKK
{
const int N=300011,maxn=262144;
const int mo=998244353,G=3,sqrt2=116195171;
lint add(lint a,lint b){return (a+=b)>=mo?a-mo:a;}
lint doadd(lint &a,lint b){if((a+=b)>=mo) a-=mo;}
lint fpow(lint a,lint p){lint ret=1;while(p){if(p&1ll) ret=ret*a%mo;a=a*a%mo;p>>=1;}return ret;}
lint wg[N],iwg[N];int rev[N],lastlen;
inline void init(){for(int i=1;i<maxn;i<<=1) wg[i]=fpow(G,(mo-1)/(i<<1)),iwg[i]=fpow(wg[i],mo-2);}
inline void getrev(int len){for(int i=1;i<len;i++)rev[i]=(rev[i>>1]>>1)|((i&1)*(len>>1));}
inline void ntt(lint *a,int len,int tp)
{
if(lastlen!=len) getrev(len),lastlen=len;
for(int i=0;i<len;i++)if(i<rev[i]) swap(a[i],a[rev[i]]);
for(int i=1;i<len;i<<=1)
{
lint w0=(~tp)?wg[i]:iwg[i];
for(int j=0;j<len;j+=(i<<1))
{
lint w=1;
for(int k=0;k<i;k++,(w*=w0)%=mo)
{
lint w1=a[j+k],w2=w*a[j+k+i]%mo;
a[j+k]=add(w1,w2),a[j+k+i]=add(w1,mo-w2);
}
}
}
lint ilen=fpow(len,mo-2);
if(tp==-1)for(int i=0;i<len;i++) (a[i]*=ilen)%=mo;
}
namespace poly
{
namespace inv
{
lint a[N],b[N];
void work(lint *f,lint *g,int n)
{
g[0]=fpow(f[0],mo-2);
for(int len=1;len<n<<1;len<<=1)
{
memcpy(a,f,len*8),memcpy(b,g,len*8);
ntt(a,len<<1,1),ntt(b,len<<1,1);
for(int i=0;i<len<<1;i++) g[i]=b[i]*(2ll-a[i]*b[i]%mo+mo)%mo;
ntt(g,len<<1,-1),memset(g+len,0,len*8);
}
memset(a,0,n*16),memset(b,0,n*16);
}
}
namespace ln
{
lint a[N],b[N];
void de(lint *f,int n){for(int i=0;i<n;i++) f[i]=f[i+1]*(i+1)%mo;f[n-1]=0;}
void ide(lint *f,int n){for(int i=n-2;i>=0;i--) f[i+1]=f[i]*fpow(i+1,mo-2)%mo;f[0]=0;}
void work(lint *f,lint *g,int n)
{
int len=n;
memcpy(a,f,len*8),de(a,len);
inv::work(f,b,len);
ntt(a,len<<1,1),ntt(b,len<<1,1);
for(int i=0;i<len<<1;i++) g[i]=a[i]*b[i]%mo;
ntt(g,len<<1,-1),ide(g,len);
memset(a,0,len*16),memset(b,0,len*16);
}
}
}
int n;
lint inv[N],fac[N],ifac[N];
void sieve(int n)
{
inv[0]=inv[1]=1;for(int i=2;i<=n;i++) inv[i]=inv[mo%i]*(mo-mo/i)%mo;
fac[0]=1;for(int i=1;i<=n;i++) fac[i]=fac[i-1]*i%mo;
ifac[0]=1;for(int i=1;i<=n;i++) ifac[i]=ifac[i-1]*inv[i]%mo;
}
lint f[N],g[N],h[N];
int main()
{
scanf("%d",&n);init();
int len=1;while(len<=n) len<<=1;
sieve(len);
g[0]=1;for(int i=1;i<len;i++)
{
g[i]=ifac[i]*fpow(fpow(sqrt2,1ll*i*i%(mo-1)),mo-2)%mo;
if(i&1) g[i]=mo-g[i];
}
poly::inv::work(g,f,len);//求出不保证联通的
for(int i=0;i<len;i++) f[i]=f[i]*fpow(sqrt2,1ll*i*i%(mo-1))%mo;//不乘fac因为还要用egf直接去ln
poly::ln::work(f,h,len);
for(int i=1;i<=n;i++) printf("%lld\n",h[i]*fac[i]%mo);
return 0;
}
}
int main(){return RKK::main();}
有标号DAG计数(生成函数)的更多相关文章
- 有标号DAG计数 [容斥原理 子集反演 组合数学 fft]
有标号DAG计数 题目在COGS上 [HZOI 2015]有标号的DAG计数 I [HZOI 2015] 有标号的DAG计数 II [HZOI 2015]有标号的DAG计数 III I 求n个点的DA ...
- P6295 有标号 DAG 计数
P6295 有标号 DAG 计数 题意 求 \(n\) 个点有标号弱联通 DAG 数量. 推导 设 \(f_i\) 表示 \(i\) 个点有标号 DAG 数量(不保证弱联通),有: \[f(i)=\s ...
- 洛谷 P6295 - 有标号 DAG 计数(生成函数+容斥+NTT)
洛谷题面传送门 看到图计数的题就条件反射地认为是不可做题并点开了题解--实际上这题以我现在的水平还是有可能能独立解决的( 首先连通这个条件有点棘手,我们尝试把它去掉.考虑这题的套路,我们设 \(f_n ...
- 题解 有标号DAG计数
题目传送门 题目大意 给出\(n\),求出对于任意\(t\in[1,n]\),点数为\(t\)的弱联通\(\texttt{DAG}\)个数.答案对\(998244353\)取模. \(n\le 10^ ...
- P6295-有标号 DAG 计数【多项式求逆,多项式ln】
正题 题目链接:https://www.luogu.com.cn/problem/P6295 题目大意 求所有\(n\)个点的弱联通\(DAG\)数量. \(1\leq n\leq 10^5\) 解题 ...
- 有标号的DAG计数(FFT)
有标号的DAG计数系列 有标号的DAG计数I 题意 给定一正整数\(n\),对\(n\)个点有标号的有向无环图(可以不连通)进行计数,输出答案\(mod \ 10007\)的结果.\(n\le 500 ...
- COGS2355 【HZOI2015】 有标号的DAG计数 II
题面 题目描述 给定一正整数n,对n个点有标号的有向无环图(可以不连通)进行计数,输出答案mod 998244353的结果 输入格式 一个正整数n 输出格式 一个数,表示答案 样例输入 3 样例输出 ...
- COGS2356 【HZOI2015】有标号的DAG计数 IV
题面 题目描述 给定一正整数n,对n个点有标号的有向无环图进行计数. 这里加一个限制:此图必须是弱连通图. 输出答案mod 998244353的结果 输入格式 一个正整数n. 输出格式 一个数,表示答 ...
- 【题解】有标号的DAG计数4
[HZOI 2015] 有标号的DAG计数 IV 我们已经知道了\(f_i\)表示不一定需要联通的\(i\)节点的dag方案,考虑合并 参考[题解]P4841 城市规划(指数型母函数+多项式Ln),然 ...
随机推荐
- Solution -「CF 855G」Harry Vs Voldemort
\(\mathcal{Description}\) Link. 给定一棵 \(n\) 个点的树和 \(q\) 次加边操作.求出每次操作后,满足 \(u,v,w\) 互不相等,路径 \((u,w ...
- php 利用 fsockopen GET/POST 提交表单及上传文件
1.GET get.php <?php$host = 'demo.fdipzone.com';$port = 80;$errno = '';$errstr = '';$timeout = 30; ...
- Spring 高级特性之二:Processor——Bean生命周期关键触发时机
任何对象都有生命周期,那么Spring Bean对象创建.管理.销毁的整个生命周期个关键触发时机如何体现呢?先说结论,后续案例验证结论. 根据上图可知,实际bean对象涉及生命周期的主要是一个构造器和 ...
- CentOS7更新OpenSSH8
今天使用漏洞扫描工具扫描了一下系统漏洞,发现有一个openssh版本的漏洞.所以本着安全的原则修复一下. 第一时间打开百度搜索相关内容,大多数是编译安装的.每个人的环境和版本也不一样.有一定连不上去的 ...
- [LeetCode]1281. 整数的各位积和之差
给你一个整数 n,请你帮忙计算并返回该整数「各位数字之积」与「各位数字之和」的差. 示例 1: 输入:n = 234 输出:15 解释: 各位数之积 = 2 * 3 * 4 = 24 各位数之和 = ...
- IDEA如何快速生成get和set方法
方法一:1.鼠标右击"Generate"2.点击"Getter and Setter",3.将定义的字段全部选中,点击OK.方法二:使用alt+insert 快 ...
- Win10系统下WampServer运行之后显示橙色如何变成绿色的方法
我们可能会安装wampserver在本地环境下测试网站,不过wampserver运行之后,wampserver的图标呈现出橙色,而不是绿色,这就说明了wampserver在本地环境没有启动成功.那么我 ...
- Virtual Box 中的虚拟系统无法调整分辨率(无法自适应窗口大小)
关于 Virtual Box 中安装好虚拟机后无法调整分辨率,即无法随 vbox 窗口大小自动调整内部虚拟机的屏幕. 网上找了百度了一遍,很多方法并不凑效,好在最后解决了,现将过程记录,以飨来者. 1 ...
- 【信而泰】网络损伤仿真,为5G应用保驾护航
5G,绝对是今年最热门的话题!2019年6月6日,工信部正式向中国电信.中国移动.中国联通.中国广电发放5G商用牌照,中国正式进入5G商用元年.5G不仅仅是一次通信技术的升级,更是开启了一个新的时代. ...
- 【C#反射】Type的用法
Type属性的应用 Type type = typeof(MyClass); Console.Write("$类型名:{ type.Name}"); Console.Write(& ...