前置:第二类斯特林数

表示把\(n\)个小球放入\(m\)个不可区分的盒子的方案数

使用容斥原理分析,假设盒子可区分枚举至少有几个盒子为空,得到通项:

\[S(n,m)=\frac{1}{m!}\sum_{k=0}^{m}(-1)^k\binom{m}{k}(m-k)^n
\]

分析

\[f(n)=\sum_{i=0}^n\sum_{j=0}^iS(i,j)2^jj!
\]

注意到\(S(n,m)=0\quad(m>n)\),因此第二个求和上限可改为\(n\),并代入第二类斯特林数的通项,得到

\[f(n)=\sum_{i=0}^n\sum_{j=0}^n\frac{1}{j!}\sum_{k=0}^j(-1)^k\frac{j!}{k!(j-k)!}(j-k)^i2^jj!
\]

\[=\sum_{j=0}^n2^jj!\sum_{k=0}^{j}\frac{(-1)^k}{k!(j-k)!}\sum_{i=0}^n(j-k)^i
\]

\[=\sum_{j=0}^n2^jj!\sum_{k=0}^{j}\frac{(-1)^k}{k!}\frac{\sum_{i=0}^n(j-k)^i}{(j-k)!}
\]

令\(g(j)=\sum_{k=0}^{j}\frac{(-1)^k}{k!}\frac{\sum_{i=0}^n(j-k)^i}{(j-k)!}\),则\(f(n)=\sum_{j=0}^n2^jj!g(j)\)

令\(a_k=\frac{(-1)^k}{k!},b_k=\frac{\sum_{i=0}^nk^i}{k!}=\frac{k^{n+1}-1}{(k-1)k!}\quad (k>1)\)

则\(g=a \otimes b\)

然后先求出\(g\),再求出\(f\)

代码

#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<ctime>
#include<iostream>
#include<string>
#include<vector>
#include<list>
#include<deque>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<algorithm>
#include<complex>
#pragma GCC optimize ("O3")
#define rg register
using namespace std;
template<class T> inline T read(T&x){
T data=0;
int w=1;
char ch=getchar();
while(!isdigit(ch))
{
if(ch=='-')
w=-1;
ch=getchar();
}
while(isdigit(ch))
data=10*data+ch-'0',ch=getchar();
return x=data*w;
}
typedef long long ll; const int mod=998244353,g=3; int rev[1<<18|7]; inline void calrev(int lim,int l)
{
rev[0]=0;
for(int i=1;i<lim;++i)
rev[i]=(rev[i>>1]>>1)|((i&1)<<(l-1));
} inline int qpow(int x,int k)
{
int ans=1;
while(k)
{
if(k&1)
ans=(ll)ans*x%mod;
x=(ll)x*x%mod,k>>=1;
}
return ans;
} inline void FFT(int*t,int lim,int type)
{
for(rg int i=0;i<lim;++i)
if(i<rev[i])
swap(t[i],t[rev[i]]);
for(rg int i=1;i<lim;i<<=1)
{
int gn=qpow(g,(mod-1)/(i<<1));
if(type==-1)
gn=qpow(gn,mod-2);
for(rg int j=0;j<lim;j+=(i<<1))
{
int gi=1;
for(rg int k=0;k<i;++k,gi=(ll)gi*gn%mod)
{
int x=t[j+k],y=(ll)gi*t[j+i+k]%mod;
t[j+k]=x+y,t[j+i+k]=x-y+mod;
if(t[j+k]>=mod)
t[j+k]-=mod;
if(t[j+i+k]>=mod)
t[j+i+k]-=mod;
}
}
}
if(type==-1)
{
int inv=qpow(lim,mod-2);
for(rg int i=0;i<lim;++i)
t[i]=(ll)t[i]*inv%mod;
}
} int fac[100010],inv[100010],pow2[100010]; int a[1<<18|7],b[1<<18|7]; int main()
{
int n;
read(n);
fac[0]=inv[0]=pow2[0]=a[0]=b[0]=1;
for(rg int i=1;i<=n;++i)
{
fac[i]=(ll)fac[i-1]*i%mod;
inv[i]=qpow(fac[i],mod-2);
pow2[i]=pow2[i-1]<<1;
if(pow2[i]>=mod)
pow2[i]-=mod;
a[i]=inv[i];
if(i&1)
a[i]=mod-a[i];
b[i]=(ll)(qpow(i,n+1)-1)%mod*inv[i]%mod*qpow(i-1,mod-2)%mod;
}
b[1]=n+1;
int lim=1,l=0;
while(lim<=n*2)
lim<<=1,++l;
calrev(lim,l);
FFT(a,lim,1);
FFT(b,lim,1);
for(rg int i=0;i<lim;++i)
a[i]=(ll)a[i]*b[i]%mod;
FFT(a,lim,-1);
int f=0;
for(rg int i=0;i<=n;++i)
{
f+=(ll)pow2[i]*fac[i]%mod*a[i]%mod;
if(f>=mod)
f-=mod;
}
printf("%d\n",f);
return 0;
}

Hint

b1不能用等比数列公式计算,必须单独处理。

我只需要n项,但是只算到n项是错的,举例答案是3次函数,我只需要2项就只求求2项,算出来就是一个1次函数,就是错的

总结:lim必须至少是待卷积式子长度的两倍

LG4091 【[HEOI2016/TJOI2016]求和】的更多相关文章

  1. 【LG4091】[HEOI2016/TJOI2016]求和

    [LG4091][HEOI2016/TJOI2016]求和 题面 要你求: \[ \sum_{i=0}^n\sum_{j=0}^iS(i,j)*2^j*j! \] 其中\(S\)表示第二类斯特林数,\ ...

  2. 洛谷 P4091 [HEOI2016/TJOI2016]求和 解题报告

    P4091 [HEOI2016/TJOI2016]求和 题目描述 在2016年,佳媛姐姐刚刚学习了第二类斯特林数,非常开心. 现在他想计算这样一个函数的值: \[ f(n)=\sum_{i=0}^n\ ...

  3. [HEOI2016/TJOI2016]求和(第二类斯特林数)

    题目 [HEOI2016/TJOI2016]求和 关于斯特林数与反演的更多姿势\(\Longrightarrow\)点这里 做法 \[\begin{aligned}\\ Ans&=\sum\l ...

  4. 【题解】P4091 [HEOI2016/TJOI2016]求和

    [题解]P4091 [HEOI2016/TJOI2016]求和 [P4091 HEOI2016/TJOI2016]求和 可以知道\(i,j\)从\(0\)开始是可以的,因为这个时候等于\(0\).这种 ...

  5. Luogu 4091 [HEOI2016/TJOI2016]求和

    BZOJ 4555 一道模板题. 第二类斯特林数有公式: $$S(n, m) = \frac{1}{m!}\sum_{i = 0}^{m}(-1)^i\binom{m}{i}(m - i)^n$$ 考 ...

  6. P4091 [HEOI2016/TJOI2016]求和(第二类斯特林数+NTT)

    传送门 首先,因为在\(j>i\)的时候有\(S(i,j)=0\),所以原式可以写成\[Ans=\sum_{i=0}^n\sum_{j=0}^nS(i,j)\times 2^j\times j! ...

  7. 【题解】Luogu P4091 [HEOI2016/TJOI2016]求和

    原题传送门 \[\begin{aligned} a n s &=\sum_{i=0}^{n} \sum_{j=0}^{i}\left\{\begin{array}{c}{i} \\ {j}\e ...

  8. BZOJ 4555 Luogu P4091 [HEOI2016/TJOI2016]求和 (第二类斯特林数)

    题目链接 (luogu) https://www.luogu.org/problem/P4091 (bzoj) https://www.lydsy.com/JudgeOnline/problem.ph ...

  9. [题解] LuoguP4091 [HEOI2016/TJOI2016]求和

    传送门 首先我们来看一下怎么求\(S(m,n)\). 注意到第二类斯特林数的组合意义就是将\(m\)个不同的物品放到\(n\)个没有区别的盒子里,不允许有空盒子的方案数. 那么将\(m\)个不同的物品 ...

随机推荐

  1. day13-类的重写和类的私有方法

    类的重写 在python中 有时需要进行重写,重写是继承机制中的一个重要部分, 可以重写一般方法也可以重写构造方法,构造方法是用来初始化新创建对象的状态. class A : def hello(se ...

  2. 利用awk处理学生成绩问题(难度较大)

    学生成绩表单如下: Name,Team,First Test, Second Test, Third Test Tom,Red,,, Joe,Green,,, Maria,Blue,,, Fred,B ...

  3. SignalR 前期简单配置

    一.随便你在哪个命名空间下新建一个Startup类,并在在该类中注册SignalR. using Owin; using System; using System.Collections.Generi ...

  4. java项目性能测试过程记录

    一 准备环境和指标 1.主机三台(linux,这里显示的都是伪主机地址):最好用干净的机子,做性能测试的时候别装其他东西在上面跑.  100.22.0.98  部署自己的项目服务 100.22.0.9 ...

  5. (C/C++学习笔记) 二十一. 异常处理

    二十一. 异常处理 ● 异常的概念 程序的错误通常包括:语法错误.逻辑错误.运行异常. 语法错误指书写的程序语句不合乎编译器的语法规则,这种错误在编译.连接时由编译器指出. 逻辑错误是指程序能顺利运行 ...

  6. CPU使用率过高分析方法

    项目过程中发现,应用服务器经常会出现CPU使用率较高的情况,需要定位出具体代码问题. 1.用top命令,根据CPU使用率排序,找出消耗cpu最高的进程 2.找出该进程下消耗CPU最高的线程(命令:to ...

  7. python笔记3-输出输入、字符串格式化

    输入.输出 python怎么来接收用户输入呢,使用input函数,python2中使用raw_input,接收的是一个字符串,输出呢,第一个程序已经写的使用print,代码入下: 1 2 name=i ...

  8. UI控件Telerik UI for WinForms发布R1 2019|附下载

    Telerik UI for WinForms拥有适用Windows Forms的110多个令人惊叹的UI控件.所有的UI for WinForms控件都具有完整的主题支持,可以轻松地帮助开发人员在桌 ...

  9. 初始化集合的花样new HashMap<String, String>{ {put("str1":"abc");} }(转)

    Map集合的普通初始化方法: Map<String, String> map = new HashMap<String, String>(); map.put("Na ...

  10. tf.nn.rnn_cell.MultiRNNCell

    Class tf.contrib.rnn.MultiRNNCell 新版 Class tf.nn.rnn_cell.MultiRNNCell 构建多隐层神经网络 __init__(cells, sta ...