LGP6295题解

DAG 弱联通太难了,有 城市规划 这道题的前车之鉴我们很明显可以直接考虑不联通,然后做一个 \(\ln\) 得到连通。

考虑枚举一个点的度数为 \(0\)。将这个点连接剩下任意 \(n-1\) 个节点,得到:

\[f[n]=\binom{n}{1}f[n-1]2^{1(n-1)} \]

这个是错的,因为有可能在 \(n-1\) 个点中存在一个度数为 \(0\) 的点,当你枚举它为度数为 \(0\) 的点时这个图会被重复计算。

那就减掉呗!然后你会发现枚举两个点也会出现类似的情况,然后再减,最后可以得到:

\[f[n]=\sum_{i=1}^{n}\binom{n}{i}(-1)^{i+1}f[n-i]2^{i(j-i)} \]

这里考虑弄成卷积:

\[\frac{f[n]}{n!}=\sum_{i=1}^{n}\frac{f[n-i]}{(n-i)!}\frac{(-1)^{i+1}}{i!}2^{\binom{n}{2}-\binom{i}{2}-\binom{n-i}{2}} \]

\[\frac{f[n]}{n!2^{\binom{n}{2}}}=\sum_{i=1}^{n}\frac{f[n-i]}{(n-i)!2^{\binom{n-i}{2}}}\times\frac{(-1)^{i+1}}{i!2^{\binom{i}{2}}} \]

\(F(x)=\sum f[i]\frac{x^i}{i!2^{\binom{i}{2}}},G(x)=\sum(-1)^{i+1}\frac{x^i}{i!2^{\binom{i}{2}}}\),那么有:

\[F(x)=F(x)G(x)+1 \]

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

然后设 \(H(x)=\sum f[i]\frac{x^i}{i!}\),我们有:

\[ans=[x^n]\ln(H(x)) \]

#include<cstdio>
#define IMP(lim,act) for(int qwq=(lim),i=0;i^qwq;++i)act
const int M=1<<18|5,mod=998244353;
int n,F[M];
int inv[M],pw2[M],ipw2[M],fac[M],ifac[M],buf[M],*w[25];
inline int Getlen(const int&n){
	int len(0);while((1<<len)<n)++len;return len;
}
inline int Add(const int&a,const int&b){
	return a+b>=mod?a+b-mod:a+b;
}
inline int Del(const int&a,const int&b){
	return b>a?a-b+mod:a-b;
}
inline void swap(int&a,int&b){
	int c=a;a=b;b=c;
}
inline int pow(int a,int b=mod-2){
	int ans(1);for(;b;b>>=1,a=1ll*a*a%mod)if(b&1)ans=1ll*ans*a%mod;return ans;
}
inline void init(const int&n){
	const int&m=Getlen(n)-1;int*now=buf;w[m]=now;now+=1<<m;
	w[m][0]=1;w[m][1]=pow(3,mod-1>>m+1);for(int i=2;i<(1<<m);++i)w[m][i]=1ll*w[m][i-1]*w[m][1]%mod;
	for(int k=m-1;k>=0&&(w[k]=now,now+=1<<k);--k)IMP(1<<k,w[k][i]=w[k+1][i<<1]);
	pw2[0]=ipw2[0]=fac[0]=fac[1]=ifac[0]=ifac[1]=inv[1]=1;pw2[1]=2;ipw2[1]=mod+1>>1;
	for(int i=2;i<=n;++i)inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;
	for(int i=1;i<=n;++i)fac[i]=1ll*fac[i-1]*i%mod,ifac[i]=1ll*ifac[i-1]*inv[i]%mod;
	for(int i=2;i<=n;++i)pw2[i]=1ll*pw2[i-1]*pw2[1]%mod,ipw2[i]=1ll*ipw2[i-1]*ipw2[1]%mod;
	for(int i=1;i<=n;++i)pw2[i]=1ll*pw2[i-1]*pw2[i]%mod,ipw2[i]=1ll*ipw2[i-1]*ipw2[i]%mod;
}
inline void DFT(int*f,const int&M){
	const int&n=1<<M;
	for(int len=n>>1,d=M-1;d>=0;--d,len>>=1)for(int k=0;k^n;k+=len<<1){
		int*W=w[d],*L=f+(k),*R=f+(k|len),x,y;IMP(len,(x=*L,y=*R)),*L++=Add(x,y),*R++=1ll**W++*Del(x,y)%mod;
	}
}
inline void IDFT(int*f,const int&M){
	const int&n=1<<M;
	for(int len=1,d=0;d^M;++d,len<<=1)for(int k=0;k^n;k+=len<<1){
		int*W=w[d],*L=f+(k),*R=f+(k|len),x,y;IMP(len,(x=*L,y=1ll**W++**R%mod)),*L++=Add(x,y),*R++=Del(x,y);
	}
	const int&k=pow(n);IMP(n,f[i]=1ll*f[i]*k%mod);for(int i=1;(i<<1)<n;++i)swap(f[i],f[n-i]);
}
inline void Inv(int*f,const int&n){
	static int b1[M],b2[M],b3[M];const int&m=Getlen(n);b1[0]=pow(f[0]);
	for(int len=1;len<=m;++len){
		IMP(1<<len-1,b2[i]=2ll*b1[i]%mod);IMP(1<<len,b3[i]=f[i]);
		DFT(b1,len+1);DFT(b3,len+1);IMP(1<<len+1,b1[i]=1ll*b1[i]*b1[i]%mod*b3[i]%mod);IDFT(b1,len+1);
		IMP(1<<len,b1[i]=Del(b2[i],b1[i])),b3[i]=b3[1<<len|i]=b1[1<<len|i]=0;
	}
	IMP(n,f[i]=b1[i]);IMP(1<<m,b1[i]=b2[i]=0);
}
inline void Der(int*f,const int&n){
	IMP(n-1,f[i]=1ll*f[i+1]*(i+1)%mod);f[n-1]=0;
}
inline void Int(int*f,const int&n){
	for(int i=n-1;i>=0;--i)f[i+1]=1ll*f[i]*inv[i+1]%mod;f[0]=0;
}
inline void Ln(int*f,const int&n){
	static int g[M];const int&len=Getlen(n+n-2);IMP(n,g[i]=f[i]);Der(f,n);Inv(g,n);
	DFT(f,len);DFT(g,len);IMP(1<<len,g[i]=1ll*g[i]*f[i]%mod),f[i]=0;IDFT(g,len);
	IMP(n-1,f[i]=g[i]);Int(f,n-1);IMP(1<<len,g[i]=0);
}
signed main(){
	scanf("%d",&n);++n;init(n<<1);IMP(n,F[i]=1ll*(i&1?mod-ifac[i]:ifac[i])*ipw2[i]%mod);Inv(F,n);
	IMP(n,F[i]=1ll*F[i]*pw2[i]%mod);Ln(F,n);printf("%d",1ll*F[n-1]*fac[n-1]%mod);
}
posted @ 2022-07-06 16:14  Prean  阅读(15)  评论(0编辑  收藏  举报
var canShowAdsense=function(){return !!0};