luogu

description

对于\(x\in[1,n]\)求\(x\)点强联通竞赛图中的哈密顿回路的期望个数膜\(998244353\)。

\(n\le10^5\)

sol

首先\(n\)点竞赛图中的哈密顿回路总共有\(\frac{n!2^{\binom n2-n}}{n}\)条。

(本质不同的有\(\frac{n!}{n}\)条,每条都存在于\(2^{\binom n2-n}\)个图内)

所以问题在于如何求\(n\)点强联通竞赛图的个数。

考虑一个\(O(n^2)\)的\(dp\),设\(f_i\)表示\(i\)个点的强联通竞赛图个数。

同时设\(g_i\)表示\(i\)个点的竞赛图个数,显然\(g_i=2^{\binom n2}\)。

转移时枚举拓扑序最小的强联通分量的大小。

\[f_i=g_i-\sum_{j=1}^{i-1}f_j\times\binom ij\times g_{i-j}
\]

然后用分治\(FFT\)可以做到两只\(\log\)。

这里讲一种生成函数的做法。

把转移式移项可得:

\[g_i=\sum_{j=1}^{i}f_j\times \binom ij\times g_{i-j}
\]

两边同除以\(i!\):

\[\frac{g_i}{i!}=\sum_{j=1}^{i}\frac{f_j}{j!}\times\frac{g_{i-j}}{(i-j)!}
\]

令:\(F(x)=\sum_{i=0}^{n}\frac{f_i}{i!}x^i,G(x)=\sum_{i=0}^{n}\frac{g_i}{i!}x^i,C(x)=\sum_{i=1}^{n}\frac{g_i}{i!}x^i\)

(注意\(G(x)\)和\(C(x)\)的区别)

那么\(F(x)G(x)=C(x)\),所以\(F(x)=\frac{C(x)}{G(x)}\)

多项式求逆即可,复杂度\(O(n\log n)\)。

code

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int N = 8e5+5;
const int mod = 998244353;
int n,jc[N],jcn[N],f[N],g[N],h[N],rev[N],og[N];
int fastpow(int a,int b){
int res=1;
while (b) {if (b&1) res=1ll*res*a%mod;a=1ll*a*a%mod;b>>=1;}
return res;
}
void ntt(int *P,int opt,int len){
int l=0;while((1<<l)<len)++l;--l;
for (int i=0;i<len;++i) rev[i]=(rev[i>>1]>>1)|((i&1)<<l);
for (int i=0;i<len;++i) if (i<rev[i]) swap(P[i],P[rev[i]]);
for (int i=1;i<len;i<<=1){
int W=fastpow(3,(mod-1)/(i<<1));
if (opt==-1) W=fastpow(W,mod-2);
og[0]=1;for (int j=1;j<i;++j) og[j]=1ll*og[j-1]*W%mod;
for (int p=i<<1,j=0;j<len;j+=p)
for (int k=0;k<i;++k){
int x=P[j+k],y=1ll*og[k]*P[j+k+i]%mod;
P[j+k]=(x+y)%mod,P[j+k+i]=(x-y+mod)%mod;
}
}
if (opt==-1) for (int i=0,Inv=fastpow(len,mod-2);i<len;++i) P[i]=1ll*P[i]*Inv%mod;
}
int A[N],B[N];
void GetInv(int *a,int *b,int len){
if (len==1) {b[0]=fastpow(a[0],mod-2);return;}
GetInv(a,b,len>>1);
for (int i=0;i<len;++i) A[i]=a[i],B[i]=b[i];
ntt(A,1,len<<1);ntt(B,1,len<<1);
for (int i=0;i<(len<<1);++i) A[i]=1ll*A[i]*B[i]%mod*B[i]%mod;
ntt(A,-1,len<<1);
for (int i=0;i<len;++i) b[i]=((b[i]+b[i])%mod-A[i]+mod)%mod;
for (int i=0;i<(len<<1);++i) A[i]=B[i]=0;
}
int main(){
scanf("%d",&n);
jc[0]=1;
for (int i=1;i<=n;++i) jc[i]=1ll*jc[i-1]*i%mod;
jcn[n]=fastpow(jc[n],mod-2);
for (int i=n;i;--i) jcn[i-1]=1ll*jcn[i]*i%mod;
int len=1;while (len<=(n<<1)) len<<=1;
for (int i=0;i<=n;++i) f[i]=h[i]=1ll*fastpow(2,1ll*i*(i-1)/2%(mod-1))*jcn[i]%mod;
GetInv(f,g,len);
for (int i=n+1;i<len;++i) f[i]=g[i]=0;h[0]=0;
ntt(g,1,len);ntt(h,1,len);
for (int i=0;i<len;++i) g[i]=1ll*g[i]*h[i]%mod;
ntt(g,-1,len);printf("1\n-1\n");
for (int i=3;i<=n;++i){
g[i]=1ll*g[i]*jc[i]%mod;
int res=1ll*jc[i]*fastpow(2,(1ll*i*(i-1)/2-i)%(mod-1))%mod*fastpow(i,mod-2)%mod;
printf("%d\n",1ll*res*fastpow(g[i],mod-2)%mod);
}
return 0;
}

最新文章

  1. CollectionView水平和竖直瀑布流的实现
  2. 四则运算项目git统计
  3. 最基本的javascript native carousel (1)
  4. java多线程系类:JUC原子类:04之AtomicReference原子类
  5. jS事件之网站常用效果汇总
  6. 通过SQL语句提取存储过程中的内容
  7. 【Android】Android 移动应用数据到SD
  8. AaronYang的C#私房菜[二][提供编程效率的技巧]
  9. [Java] Steam文件输入流
  10. java SecurityManager
  11. [BZOJ 2500] 幸福的道路
  12. 【游戏周边】Unity,UDK,Unreal Engine4或者CryENGINE——我应该选择哪一个游戏引擎
  13. ubuntu 16.04安装perf
  14. Exceptionless 生产部署笔记
  15. 操纵Review被封店,申诉信
  16. LIMIT用法
  17. 构建一个Gods Eye Android应用程序:第1部分 – 收集已安装的Android应用程序
  18. PHP 小知识
  19. 【linux】——ubuntu12.04 下安装wine和wine乱码解决方案
  20. 通用的sql语句

热门文章

  1. HTML5如何做横屏适配
  2. css中pt、px、em、ex、in等这类长度单位详细说明
  3. HttpConnection的使用
  4. 二十六 Python分布式爬虫打造搜索引擎Scrapy精讲—通过downloadmiddleware中间件全局随机更换user-agent浏览器用户代理
  5. python环境配置
  6. Python抓取糗事百科成人版图片
  7. 转:Hive SQL的编译过程
  8. Qt中使用ActiveX控件
  9. CF910C
  10. SQLServer中通过脚本内容查找存储过程