题目

场面过度玄学,容易引起不适

我们发现我们要求的这个期望由分母和分子两部分构成

易发现

\[Ans=\frac{\sum_{i=1}^nS_2(n,i)\times i\times i!}{\sum_{i=1}^nS_2(n,i)\times i!}
\]

结合\(NTT\)求斯特林数卷积我们就能过掉\(subtask2\)

考虑正解,我们显然不能再用斯特林数搞了

于是考虑一下\(dp\)

设\(f_n\)表示分母,即\(f_n=\sum_{i=1}^nS_2(n,i)\times i!\)

我们发现

\[f_i=\sum_{j=1}^{i}f_{i-j}\binom{i}{j}
\]

我们强行规定\(f_0=1\)

这个柿子我们可以这样理解,先从\(i\)个数里选取\(j\)个数作为第一组,之后剩下的\(i-j\)在后面自由形成若干组

这非常正确,因为对于任何一种情况,其每一分组都有机会被选中成为第一组,而剩下的组会任意排列,于是正确性显然

我们考虑拆开组合数

\[f_i=\sum_{j=1}^if_{i-j}\frac{i!}{j!(i-j)!}
\]

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

设\(f'_i=\frac{f_i}{i!},g_i=\frac{1}{i!}\)

写成生成函数,别忘了我们强行规定\(f_0=1\)

\[F'=\sum_{i=0}(\sum_{j=1}^if'_{i-j}g_j+[i=0])x^i
\]

\[F'=1+F'G
\]

于是\(F'=(1-G)^{-1}\)

但是发现好像不太得劲,因为 \(1-G\)的最低项为\(0\),我们没法求逆

但是我们注意到\(g_0\)全程都没有出现,于是我们又强行规定\(g_0=0\)

于是我们现在可以愉快的求逆了

同理我们也可以表示出分母上的柿子

\[h_i=\sum_{j=1}^i\binom{i}{j}h_{i-j}+\binom{i}{j}f_{i-j}=f_i+\sum_{j=1}^i\binom{i}{j}h_{i-j}
\]

这里不需要强行\(h_0=1\)了

我们还是按照刚才的套路得到

\[H'=\frac{1}{(1-G)^2}
\]

但是并不知道为什么这里答案算出来总会多\(1\)

肯定是我太菜了生成函数求错了

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define re register
#define LL long long
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
const int maxn=262144+1005;
inline int read() {
char c=getchar();int x=0;while(c<'0'||c>'9') c=getchar();
while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-48,c=getchar();return x;
}
int n,ask[100005],len,rev[maxn],T;
const LL mod=998244353;
const LL G[2]={3,332748118};
LL fac[maxn],ifac[maxn];
LL D[maxn],C[maxn],K[maxn],a[maxn],b[maxn],c[maxn],t[maxn];
inline LL ksm(LL a,LL b) {LL S=1;while(b) {if(b&1) S=S*a%mod;b>>=1;a=a*a%mod;}return S;}
inline void NTT(LL *f,int o) {
for(re int i=0;i<len;i++) if(i<rev[i]) std::swap(f[i],f[rev[i]]);
for(re int i=2;i<=len;i<<=1) {
int ln=i>>1;LL og1=ksm(G[o],(mod-1)/i);
for(re int l=0;l<len;l+=i) {
LL t,og=1;
for(re int x=l;x<l+ln;x++) {
t=(og*f[ln+x])%mod;
f[ln+x]=(f[x]-t+mod)%mod;
f[x]=(f[x]+t)%mod;
og=(og*og1)%mod;
}
}
}
if(!o) return;
LL inv=ksm(len,mod-2);
for(re int i=0;i<len;i++) f[i]=(f[i]*inv)%mod;
}
inline void mul(int n,LL *A,LL *B) {
len=1;while(len<n+n) len<<=1;
for(re int i=0;i<len;i++) rev[i]=rev[i>>1]>>1|((i&1)?len>>1:0);
NTT(A,0),NTT(B,0);for(re int i=0;i<len;i++) A[i]=(A[i]*B[i])%mod;
NTT(A,1);for(re int i=n;i<len;i++) A[i]=0;
}
inline void Inv(int n,LL *A,LL *B) {
if(n==1) {B[0]=ksm(A[0],mod-2);return;}
Inv((n+1)>>1,A,B);
memset(C,0,sizeof(C));memset(K,0,sizeof(K)),memset(D,0,sizeof(D));
for(re int i=0;i<n;i++) C[i]=A[i],D[i]=K[i]=B[i];
mul(n,K,C);mul(n,K,D);
for(re int i=0;i<n;i++) B[i]=(2ll*B[i]-K[i]+mod)%mod;
}
int main() {
T=read();
for(re int i=1;i<=T;i++)
ask[i]=read(),n=max(n,ask[i]+1);
fac[0]=1;
for(re LL i=1;i<n;i++) fac[i]=(fac[i-1]*i)%mod;
ifac[n-1]=ksm(fac[n-1],mod-2);
for(re LL i=n-2;i>=0;--i) ifac[i]=(ifac[i+1]*(i+1))%mod;
for(re int i=0;i<n;i++)
b[i]=mod-ifac[i],b[i]%=mod;
b[0]=1;b[0]%=mod;
Inv(n,b,a);
for(re int i=0;i<n;i++) t[i]=c[i]=a[i];
mul(n,t,c);
for(re int i=1;i<=T;i++) {
LL q=t[ask[i]],p=a[ask[i]];
printf("%lld\n",q*ksm(p,mod-2)%mod-1);
}
return 0;
}

【LGP5162】WD与积木的更多相关文章

  1. 洛谷 P5162 WD与积木 解题报告

    P5162 WD与积木 题目背景 WD整日沉浸在积木中,无法自拔-- 题目描述 WD想买\(n\)块积木,商场中每块积木的高度都是\(1\),俯视图为正方形(边长不一定相同).由于一些特殊原因,商家会 ...

  2. [P5162] WD与积木

    每种堆法(理解成名次序列,举例3,3,8,2和7,7,100,2都对应2,2,1,3这个名次序列)等概率出现:题目中"两种堆法不同当且仅当某个积木在两种堆法中处于不同的层中"可见这 ...

  3. 洛谷P5162 WD与积木 [DP,NTT]

    传送门 思路 真是非常套路的一道题-- 考虑\(DP\):设\(f_n\)为\(n\)个积木能搭出的方案数,\(g_n\)为所有方案的高度之和. 容易得到转移方程: \[ \begin{align*} ...

  4. Luogu5162 WD与积木(生成函数+多项式求逆)

    显然的做法是求出斯特林数,但没有什么优化空间. 考虑一种暴力dp,即设f[i]为i块积木的所有方案层数之和,g[i]为i块积木的方案数.转移时枚举第一层是哪些积木,于是有f[i]=g[i]+ΣC(i, ...

  5. [Luogu5162]WD与积木(多项式求逆)

    不要以为用上Stirling数就一定离正解更近,FFT都是从DP式本身出发的. 设f[i]为i个积木的所有方案的层数总和,g[i]为i个积木的方案数,则答案为$\frac{f[i]}{g[i]}$ 转 ...

  6. 洛谷 P5162 WD与积木【多项式求逆】

    设f[i]为i个积木能堆出来的种类,g[i]为i个积木能堆出来的种类和 \[ f[n]=\sum_{i=1}^{n}C_{n}^{i}g[n-i] \] \[ g[n]=\sum_{i=1}^{n}C ...

  7. P5162 WD与积木(多项式求逆+生成函数)

    传送门 题解 比赛的时候光顾着算某一个\(n\)的答案是多少忘了考虑不同的\(n\)之间的联系了--而且我也很想知道为什么推着推着会变成一个二项式反演-- 设\(f_n\)为\(n\)块积木时的总的层 ...

  8. [luogu5162]WD与积木

    设$g_{n}$表示$n$个积木放的方案数,枚举最后一层所放的积木,则有$g_{n}=\sum_{i=1}^{n}c(n,i)g_{n-i}$(因为积木有编号的所以要选出$i$个) 将组合数展开并化简 ...

  9. 【LUOGU???】WD与积木 NTT

    题目大意 把 \(n\) 个有标号物品分到一些有标号的箱子中且不允许为空,问期望箱子的数量. 多组询问. \(n\leq 100000\) 题解 记 \(f_i\) 为 \(i\) 个有标号物品分到一 ...

随机推荐

  1. 【SSH网上商城项目实战15】线程、定时器同步首页数据(类似于博客定期更新排名)

    转自:https://blog.csdn.net/eson_15/article/details/51387378 上一节我们做完了首页UI界面,但是有个问题:如果我在后台添加了一个商品,那么我必须重 ...

  2. Java 泛型的使用

    一.泛型的简介1.为什么要使用泛型? 一般使用在集合上,比如现在把一个字符串类型的值放入到集合里面,这个时候,这个值放到集合之后,失去本身的类型,只能是object类型.这时,如果想要对这个值进行类型 ...

  3. python安装后无法用cmd命令pip 装包

    出现问题: 原因:没有添加环境变量. 解决方法:将python安装目录下的Script目录添加进环境变量,其中有pip.exe,在cmd中输入pip install命令时要运行pip.exe. win ...

  4. Ajax实现表格实时编辑

    如果我们的对于一个表格中所有的数据都能在本页进行操作那该是多酷炫的一件事(用起来炒鸡爽)! 用Ajax就可以实现这个功能啦.废话不多说,下面贴出我写的demo吧哈哈.我用的TP框架(3.2)比较习惯啦 ...

  5. WinForm实现Rabbitmq官网6个案例-RPC

    获取源码 客户端代码: namespace RabbitMQDemo { public partial class RPC : Form { private readonly static RPC _ ...

  6. Python库安装注意事项

    由于一些python库依赖其它库或者其它组件,因此,在使用pip3命令安装python库的时候,经常会报错,告知缺失哪些组件. 但是, 开启VPN后,就没有再碰到类似错误,相关组件都是自动被安装. 因 ...

  7. PHP匿名函数(闭包)

    匿名函数(Anonymous functions),也叫闭包函数(closures),允许 临时创建一个没有指定名称的函数.最经常用作回调函数(callback)参数的值.当然,也有其它应用的情况. ...

  8. linux_day3

    1.grep与find的区别? grep是查找文件内的字符而find则是查找文件 2.显示/etc/passwd中以nologin结尾的行 3. 输入ip addr命令后,过滤出包含ip的行 ip a ...

  9. js不管条件是否成立都要进行变量提升

    ### 不管条件是否成立都要进行变量提升 > 不管条件是否成立,判断体中出现的var/function都会进行变量提升:但是在最新浏览器版本当中,function声明的变量只能提前声明,不能定义 ...

  10. 让UpdatePanel支持文件上传(2):服务器端组件 .

    我们现在来关注服务器端的组件.目前的主要问题是,我们如何让页面(事实上是ScriptManager控件)认为它接收到的是一个异步的回送?ScriptManager控件会在HTTP请求的Header中查 ...