• LG4233 射命丸文的笔记


    射命丸文的笔记

    如果一个竞赛图含有哈密顿回路,则称这张竞赛图为值得记录的。

    从所有含有 (n) 个顶点(顶点互不相同)的,值得记录的竞赛图中等概率随机选取一个。求选取的竞赛图中哈密顿回路数量的期望值。

    答案对 (998244353) 取模。若不存在这样的竞赛图输出-1。

    (n leq 10^5)

    题解

    考虑分别计算分子和分母。

    分子就是哈密顿回路的总数,可以使用期望的线性性来求它。

    一共有 ((n-1)!) 种哈密顿回路,每种哈密顿回路出现在 (2^{inom{n}{2}-n}) 种竞赛图里,所以 (n) 个点的竞赛图中哈密顿回路的总数是 ((n-1)! 2^{inom{n}{2}-n}) 条。

    分子就是强连通竞赛图的数量,可以使用生成函数来求它。

    (n) 个点有标号强连通竞赛图的数量为 (f_n)。竞赛图总数是 (g_n=2^{inom{n}{2}})

    枚举拓扑序最小的强连通分量大小为 (i),则该强连通分量向其他的点连边的方向是固定的,剩下((n-i))个点的边任意连,所以

    [f_n=g_n-sum_{i=1}^{n-1}inom{n}{i}f_ig_{n-i}\ g_n=sum_{i=1}^ninom{n}{i}f_ig_{n-i} ]

    (f,g) 的EGF为 (F(x),G(x)),那么

    [G(x)-g_0=F(x)G(x)\ F(x)=1-frac{g_0}{G(x)} ]

    多项式求逆即可。时间复杂度 (O(nlog n))

    CO int N=262144;
    int omg[2][N],rev[N];
    int fac[N],inv[N],ifac[N];
    
    void NTT(poly&a,int dir){
    	int lim=a.size(),len=log2(lim);
    	for(int i=0;i<lim;++i) rev[i]=rev[i>>1]>>1|(i&1)<<(len-1);
    	for(int i=0;i<lim;++i)if(i<rev[i]) swap(a[i],a[rev[i]]);
    	for(int i=1;i<lim;i<<=1)
    		for(int j=0;j<lim;j+=i<<1)for(int k=0;k<i;++k){
    			int t=mul(omg[dir][N/(i<<1)*k],a[j+i+k]);
    			a[j+i+k]=add(a[j+k],mod-t),a[j+k]=add(a[j+k],t);
    		}
    	if(dir==1){
    		int ilim=fpow(lim,mod-2);
    		for(int i=0;i<lim;++i) a[i]=mul(a[i],ilim);
    	}
    }
    poly operator~(poly a){
    	int n=a.size();
    	poly b={fpow(a[0],mod-2)};
    	if(n==1) return b;
    	a.resize(1<<(int)ceil(log2(n)));
    	for(int lim=2;lim<2*n;lim<<=1){
    		poly c(a.begin(),a.begin()+lim);
    		c.resize(lim<<1),NTT(c,0);
    		b.resize(lim<<1),NTT(b,0);
    		for(int i=0;i<lim<<1;++i) b[i]=mul(2+mod-mul(c[i],b[i]),b[i]);
    		NTT(b,1),b.resize(lim);
    	}
    	return b.resize(n),b;
    }
    
    int main(){
    	omg[0][0]=1,omg[0][1]=fpow(3,(mod-1)/N);
    	omg[1][0]=1,omg[1][1]=fpow(omg[0][1],mod-2);
    	fac[0]=fac[1]=1;
    	inv[0]=inv[1]=1;
    	ifac[0]=ifac[1]=1;
    	for(int i=2;i<N;++i){
    		omg[0][i]=mul(omg[0][i-1],omg[0][1]);
    		omg[1][i]=mul(omg[1][i-1],omg[1][1]);
    		fac[i]=mul(fac[i-1],i);
    		inv[i]=mul(mod-mod/i,inv[mod%i]);
    		ifac[i]=mul(ifac[i-1],inv[i]);
    	}
    	int n=read<int>();
    	poly g(n+1);
    	for(int i=0;i<=n;++i) g[i]=mul(fpow(2,(int64)i*(i-1)/2%(mod-1)),ifac[i]);
    	poly f=~g;
    	for(int i=3;i<=n;++i) f[i]=mul(mod-f[i],fac[i]);
    	if(n>=1) puts("1");
    	if(n>=2) puts("-1");
    	for(int i=3;i<=n;++i){
    		int ans=mul(fac[i-1],mul(fpow(2,(int64)i*(i-3)/2%(mod-1)),fpow(f[i],mod-2)));
    		printf("%d
    ",ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    iommu分析之smmu v3的实现
    关于virtio_net网卡命名的小问题
    Affinity broken due to vector space exhaustion 问题
    iommu系列之概念解释篇
    获取客户端Mac地址
    SqList *L 和 SqList * &L的区别/学习数据结构突然发现不太懂 小祥我查找总结了一下
    前端页面报表图在线js库
    MybatisPlus自动填充
    SpringBoot集成druid开启内置监控页面
    简单的系统用户权限设计图
  • 原文地址:https://www.cnblogs.com/autoint/p/12185563.html
Copyright © 2020-2023  润新知