思路

题目要求求的是哈密顿回路的期望数量,实际上就是哈密顿回路的总数/有哈密顿回路的竞赛图的数量

n个点的所有竞赛图中哈密顿回路的总数为

\[(n-1)! 2^{\frac{n(n-1)}{2}-n}
\]

每个哈密顿回路可以看成一个环,则经过的n个节点就是长度为n的一个排列,排列总数为\(n!\) 个,每个回路被计数了n次,有\((n-1)!\)种,剩下的\(\frac{n(n-1)}{2}-n\)条边随便连,有\(2^{\frac{(n-1)n}{2}-n}\)种

而强连通竞赛图中必有一个哈密顿回路

而i个点的竞赛图总数为

\[2^{\frac{n(n-1)}{2}}
\]

设i个点的竞赛图总数为\(g_i=2^{\frac{i(i-1)}{2}}\),i个点强连通竞赛图总数为\(f_i\)

可以枚举拓扑序最小的强连通分量大小,然后用总数减去不强连通的竞赛图总数即可

为什么枚举拓扑序最小?因为枚举拓扑序最小同时确定了每条边的方向并保证了整个图不会强连通

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

所以

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

拆开组合数

\[\begin{align}g_i=&\sum_{j=1}^{i} f_j \binom{i}{j} g_{i-j}\\=& i!\sum_{j=1}^i \frac{f_{j}}{j!}\frac{g_{i-j}}{(i-j)!}\end{align}
\]

所以

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

设\(F_i=\frac{f_i}{i!}\),\(G_i=\frac{g_i}{i!}\)

就变成了这样

\[G_i=\sum_{j=1}^i G_{i-j}F_j
\]

然后上分治FFT或者多项式求逆就好了

代码

#include <cstdio>
#include <algorithm>
#include <cstring>
#define int long long
using namespace std;
const int MAXN = 300000;
const int MOD = 998244353;
const int G = 3;
const int invG = 332748118;
int rev[MAXN];
void cal_rev(int n,int lim){
for(int i=0;i<n;i++)
rev[i]=(rev[i>>1]>>1)|((i&1)<<(lim-1));
}
int pow(int a,int b){
int ans=1;
while(b){
if(b&1)
ans=(1LL*ans*a)%MOD;
a=(1LL*a*a)%MOD;
b>>=1;
}
return ans;
}
void NTT(int *a,int opt,int n,int lim){
for(int i=0;i<n;i++)
if(i<rev[i])
swap(a[i],a[rev[i]]);
for(int i=2;i<=n;i<<=1){
int len=i/2,tmp=pow((opt)?G:invG,(MOD-1)/i);
for(int j=0;j<n;j+=i){
int arr=1;
for(int k=j;k<j+len;k++){
int t=(1LL*a[k+len]*arr)%MOD;
a[k+len]=(a[k]-t+MOD)%MOD;
a[k]=(a[k]+t)%MOD;
arr=(1LL*arr*tmp)%MOD;
}
}
}
if(!opt){
int invN = pow(n,MOD-2);
for(int i=0;i<n;i++)
a[i]=(1LL*a[i]*invN)%MOD;
}
}
void Inv(int *a,int *b,int dep,int &midlen,int &midlim){
if(dep==1){
b[0]=pow(a[0],MOD-2);
return;
}
Inv(a,b,(dep+1)>>1,midlen,midlim);
static int tmp[MAXN];
while((dep<<1)>midlen)
midlen<<=1,midlim++;
for(int i=0;i<dep;i++)
tmp[i]=a[i];
for(int i=dep;i<midlen;i++)
tmp[i]=0;
cal_rev(midlen,midlim);
NTT(b,1,midlen,midlim);
NTT(tmp,1,midlen,midlim);
for(int i=0;i<midlen;i++)
b[i]=1LL*b[i]*(2LL-1LL*b[i]*tmp[i]%MOD+MOD)%MOD;
NTT(b,0,midlen,midlim);
for(int i=dep;i<midlen;i++)
b[i]=0;
}
int jc[MAXN],jc_inv[MAXN],n;
void init(int n){
jc[0]=1;
for(int i=1;i<=n;i++)
jc[i]=(1LL*jc[i-1]*i)%MOD;
jc_inv[n]=pow(jc[n],MOD-2);
for(int i=n-1;i>=0;i--)
jc_inv[i]=(1LL*jc_inv[i+1]*(i+1))%MOD;
}
int f[MAXN],g[MAXN];
signed main(){
scanf("%lld",&n);
init(n);
int inv2=pow(2,MOD-2);
for(int i=1;i<=n;i++)
g[i]=(1LL*pow(2,(1LL*i*(i-1)/2)%(MOD-1))*jc_inv[i]%MOD);
g[0]=1;
int midlen=1,midlim=0;
Inv(g,f,n+1,midlen,midlim);
for(int i=1;i<=n;i++){
if(i==1)
printf("1\n");
else if(i==2)
printf("-1\n");
else
printf("%lld\n",MOD-1LL*jc[i-1]*pow(2,i*(i-3)/2%(MOD-1))%MOD*pow(1LL*f[i]*jc[i]%MOD,MOD-2)%MOD);
}
return 0;
}

P4233 射命丸文的笔记的更多相关文章

  1. 洛谷P4233 射命丸文的笔记 【多项式求逆】

    题目链接 洛谷P4233 题解 我们只需求出总的哈密顿回路个数和总的强联通竞赛图个数 对于每条哈密顿回路,我们统计其贡献 一条哈密顿回路就是一个圆排列,有\(\frac{n!}{n}\)种,剩余边随便 ...

  2. LuoguP4233 射命丸文的笔记

    题目描述 求所有\(n\)个点带标号强连通竞赛图中哈密顿回路数量的平均值. 题解 因为要求平均数,所以我们可以把分母和分子单开来算. \(n\)个点的所有竞赛图的所有哈密顿回路个数是可以求出来的,就是 ...

  3. [Luogu4233]射命丸文的笔记

    luogu description 对于\(x\in[1,n]\)求\(x\)点强联通竞赛图中的哈密顿回路的期望个数膜\(998244353\). \(n\le10^5\) sol 首先\(n\)点竞 ...

  4. Luogu4233 射命丸文的笔记 DP、多项式求逆

    传送门 注意到总共有\(\frac{n!}{n}\)条本质不同的哈密顿回路,每一条哈密顿回路恰好会出现在\(2^{\binom{n}{2} - n}\)个图中,所以我们实际上要算的是强连通有向竞赛图的 ...

  5. ZJOI2019一轮停课刷题记录

    Preface 菜鸡HL终于狗来了他的省选停课,这次的时间很长,暂定停到一试结束,不过有机会二试的话还是可以搞到4月了 这段时间的学习就变得量大而且杂了,一般以刷薄弱的知识点和补一些新的奇怪技巧为主. ...

  6. 省选前的th题

    沙茶博主终于整完了知识点并学完了早该在NOIP之前学的知识们 于是终于开始见题了,之前那个奇怪的题单的结果就是这个了 题目按沙茶博主的做题顺序排序 个人感觉(暂时)意义不大的已被自动忽略 洛谷 491 ...

  7. git-简单流程(学习笔记)

    这是阅读廖雪峰的官方网站的笔记,用于自己以后回看 1.进入项目文件夹 初始化一个Git仓库,使用git init命令. 添加文件到Git仓库,分两步: 第一步,使用命令git add <file ...

  8. js学习笔记:webpack基础入门(一)

    之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...

  9. SQL Server技术内幕笔记合集

    SQL Server技术内幕笔记合集 发这一篇文章主要是方便大家找到我的笔记入口,方便大家o(∩_∩)o Microsoft SQL Server 6.5 技术内幕 笔记http://www.cnbl ...

随机推荐

  1. Python+Selenium+PageObject

    一.安装page_objects测试库 二.目录介绍 1.pages包:用于各界面元素定位,如BaseLoginPage.py 2.testcases包:用于编写各功能测试用例,如Login.py 3 ...

  2. 【大数据和云计算技术社区】分库分表技术演进&最佳实践笔记

    1.需求背景 移动互联网时代,海量的用户每天产生海量的数量,这些海量数据远不是一张表能Hold住的.比如 用户表:支付宝8亿,微信10亿.CITIC对公140万,对私8700万. 订单表:美团每天几千 ...

  3. oracle树形结构全路径查询

    很实用的语法,父子节点通过id与patientId来关联,知道子节点的id,想查出所有的父节点: START WITH ...CONNECT BY ... SELECT T2.ORG_FULLNAME ...

  4. MongoDB3.2新特性之部分索引

    官方介绍:https://docs.mongodb.org/manual/core/index-partial/ mongodb3.2支持对某个集合的部分数据创建索引.如给年龄大于十八岁的数据创建索引 ...

  5. Cocos Creator 构建发布... APP ABI(选项)

    APP ABI 选项对应的是设备的 CPU 架构.勾选不同的值,编译出来的 apk 可以适用于不同的设备.勾选的越多,适配的机器越多.但是相应的 apk 包体越大. 需要根据自己的项目实际情况决定要编 ...

  6. Java基础之数组详解

    数组对于每一门编程语言来说都是重要的数据结构之一,当然不同语言对数组的实现及处理也不尽相同. Java 语言中提供的数组是用来存储固定大小的同类型元素. 你可以声明一个数组变量,如 numbers[1 ...

  7. C++模板类中友元函数的写法

    首先,已声明好的类Triangle file://Triangle.h template<class T> class Triangle{ public: Triangle(T width ...

  8. linux 笔记 第一天

    打开终端:ctrl+alt+t 清屏:ctrl+l 在终端在退出锁定:ctrl+c 目录:又称为文件夹,是包含所有的文件 目录创建规则: 1.大小是256 2.不能包含特殊字符 3.见名知义 路径:是 ...

  9. rinetd 通过公网连接云数据库

    在很多云服务中,经常会遇到云存储数据库没有公网(外网)地址,只有内网地址,这导致在公司网无法访问,这是一个很困扰的问题,这时我们可以使用rinetd进行转发实现外网连接. 首先需要一台能够连接上数据库 ...

  10. WCF 重载

    [ServiceContract] public interface IUser { [OperationContract(Name="ByUseId")] User GetUse ...