4555: [Tjoi2016&Heoi2016]求和

题意:求$$

\sum_{i=0}^n \sum_{j=0}^i S(i,j)\cdot 2^j\cdot j! \

S是第二类斯特林数

\[
***

首先你要把这个组合计数肝出来,~~于是我去翻了一波《组合数学》~~

*用斯特林数容斥原理推导那个式子可以直接出卷积形式,见下一篇,本篇是分治fft做法*

</br>
###组合计数

**斯特林数** $S(n,i)$表示将n个不同元素划分成i个相同集合非空的方案数
**Bell数** $B(n)=\sum\limits_{i=0}^n S(n,i)$也就是分成任意个相同的集合
有一个递推式
\]

B(n) = \sum_{i=0}^{n-1} \binom{n-1}{n-1-i}B(i) = \sum_{i=0}^{n-1} \binom{n-1}{i}B(i)

\[$推导$:
考虑和第一个元素在同一个集合的元素有几个,剩下的是子问题
或者这么想,因为每个集合相同,我们规定第一个元素在一个集合后这个集合就不相同了,剩下的元素分入这个不相同的集合或者成为子问题
</br>

$S'(n,i)=S(n,i)*i!$就是**集合不相同**啦,
\]

B'(n) = \sum_{i=1}^n \binom{n}{i}B'(n-i)

\[$推导$:
因为每个集合都不相同,我们没有必要规定第一个元素在集合里了,直接枚举第一个集合元素个数就可以了

</br>
然后那个$2^j$可以认为每个集合有两种颜色,枚举当前集合顺便枚举颜色,乘上一个2就行了

令$f(n)=2 \sum\limits_{i=1}^n \binom{n}{i} f(n-i)$,答案就是$\sum_{i=0}^n f(i)$
快速求出f就可以做了,整理一下发现
\]

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

\[是一个卷积的形式,但是两边都有f,所以要用**CDQ分治套FFT**

</br>
###分治fft
和CDQ分治一样,每次用$[l,mid]$更新$[mid+1,r]$
可以发现,$f(i)[mid+1,r]$都是$\frac{f(i)}{i!}[l,mid]$卷上$\frac{1}{i!}[1,r-l]$的结果
我们把两个函数$[l,mid]$和$[1,r-l]$的部分拿出来做卷积,更新$[mid+1,r]$
可以认为先把向量移动了l位

复杂度$O(nlog^2n)$,13560ms,~~貌似别人的分治fft更慢20000ms多~~
</br>
注意初始值$f[0]=1$因为$S(0,0)=1$,以及cdq(0,n)

</br>
###多项式求逆
当然也可以,具体看[51nod这篇讨论](http://www.51nod.com/question/index.html#!questionId=1713)吧
把$f_0 x^0$单独拿出来的思想比较有意思,$A(x)$从0开始,$B(x)$从1开始($B_0 = 0$)
$$A(x) = F_0 x^0 + A(x) B(x)\]

update 2017.5.3 : 发现tls貌似补了一句\(2x e^x\),求这个东西来做也可以,但不如直接处理处B来方便

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long ll;
const int N=(1<<18)+5, INF=1e9;
const ll P=998244353, g=3;
inline int read(){
char c=getchar();int x=0,f=1;
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
return x*f;
} ll Pow(ll a, ll b) {
ll ans=1;
for(; b; b>>=1, a=a*a%P)
if(b&1) ans=ans*a%P;
return ans;
} int n, rev[N];
ll inv[N], fac[N], facInv[N];
ll f[N], a[N], b[N];
void dft(ll *a, int n, int flag) {
for(int i=0; i<n; i++) if(i<rev[i]) swap(a[i], a[rev[i]]);
for(int l=2; l<=n; l<<=1) {
int m=l>>1;
ll wn = Pow(g, flag==1 ? (P-1)/l : P-1-(P-1)/l);
for(ll *p=a; p!=a+n; p+=l) {
ll w=1;
for(int k=0; k<m; k++) {
ll t = w*p[k+m];
p[k+m]=(p[k]-t+P)%P;
p[k]=(p[k]+t)%P;
w=w*wn%P;
}
}
}
if(flag==-1) {
ll inv=Pow(n, P-2);
for(int i=0; i<n; i++) a[i]=a[i]*inv%P;
}
}
void cdq(int l, int r) {
if(l==r) return;
int mid=(l+r)>>1;
cdq(l, mid);
int lim=r-l+1, n=1, k=0;
while(n<lim) n<<=1, k++;
for(int i=0; i<n; i++) rev[i] = (rev[i>>1]>>1) | ((i&1)<<(k-1)); for(int i=0; i<n; i++) a[i]=b[i]=0;
for(int i=l; i<=mid; i++) a[i-l] = f[i];
for(int i=0; i<=r-l; i++) b[i] = facInv[i];
dft(a, n, 1); dft(b, n, 1);
for(int i=0; i<n; i++) a[i]=a[i]*b[i]%P;
dft(a, n, -1); for(int i=mid+1; i<=r; i++) f[i]=(f[i] + 2*a[i-l])%P;
cdq(mid+1, r);
}
int main() {
freopen("in","r",stdin);
n=read();
inv[1]=1; fac[0]=facInv[0]=1;
for(int i=1; i<=n; i++) {
if(i!=1) inv[i] = (P-P/i)*inv[P%i]%P;
fac[i] = fac[i-1]*i%P;
facInv[i] = facInv[i-1]*inv[i]%P;
}
f[0]=1;
cdq(0, n);
ll ans=0;
for(int i=0; i<=n; i++) ans = (ans + f[i]*fac[i]%P)%P;
if(ans<0) ans+=P;
printf("%lld\n", ans);
}

BZOJ 4555: [Tjoi2016&Heoi2016]求和 [分治FFT 组合计数 | 多项式求逆]的更多相关文章

  1. BZOJ 4555 [Tjoi2016&Heoi2016]求和 ——分治 NTT 多项式求逆

    不想多说了,看网上的题解吧,我大概说下思路. 首先考察Stirling的意义,然后求出递推式,变成卷积的形式. 然后发现贡献是一定的,我们可以分治+NTT. 也可以直接求逆(我不会啊啊啊啊啊) #in ...

  2. BZOJ 4555: [Tjoi2016&Heoi2016]求和 [FFT 组合计数 容斥原理]

    4555: [Tjoi2016&Heoi2016]求和 题意:求\[ \sum_{i=0}^n \sum_{j=0}^i S(i,j)\cdot 2^j\cdot j! \\ S是第二类斯特林 ...

  3. [BZOJ4555][TJOI2016&HEOI2016]求和(分治FFT)

    4555: [Tjoi2016&Heoi2016]求和 Time Limit: 40 Sec  Memory Limit: 128 MBSubmit: 525  Solved: 418[Sub ...

  4. bzoj 4555 [Tjoi2016&Heoi2016]求和 NTT 第二类斯特林数 等比数列求和优化

    [Tjoi2016&Heoi2016]求和 Time Limit: 40 Sec  Memory Limit: 128 MBSubmit: 679  Solved: 534[Submit][S ...

  5. BZOJ 4555 [Tjoi2016&Heoi2016]求和 (多项式求逆)

    题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=4555 题目大意: 给定 \(S(n,m)\) 表示第二类斯特林数,定义函数 \(f(n ...

  6. bzoj 4555: [Tjoi2016&Heoi2016]求和【NTT】

    暴力推式子推诚卷积形式,但是看好多blog说多项式求逆不知道是啥.. \[ \sum_{i=0}^{n}\sum_{j=0}^{n}S(i,j)*2^j*j! \] \[ S(i,j)=\frac{1 ...

  7. 洛谷P4721 【模板】分治 FFT(生成函数+多项式求逆)

    传送门 我是用多项式求逆做的因为分治FFT看不懂…… upd:分治FFT的看这里 话说这个万恶的生成函数到底是什么东西…… 我们令$F(x)=\sum_{i=0}^\infty f_ix^i,G(x) ...

  8. [BZOJ 4555][Tjoi2016&Heoi2016]求和

    题意 给定 $n$ , 求下式的值: $$ f(n)= \sum_{i=0}^n\sum_{j=0}^i\begin{Bmatrix}i\\ j\end{Bmatrix}\times 2^j\time ...

  9. BZOJ 4555: [Tjoi2016&Heoi2016]求和 (NTT + 第二类斯特林数)

    题意 给你一个数 \(n\) 求这样一个函数的值 : \[\displaystyle f(n)=\sum_{i=0}^{n}\sum_{j=0}^{i} \begin{Bmatrix} i \\ j ...

随机推荐

  1. 命运(经典dp)

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=2571 命运 Time Limit: 2000/1000 MS (Java/Others)    Mem ...

  2. JS 监听浏览器各个标签间的切换

    以前看到过一些网页,在标签切换到其它地址时,网页上的标题上会发生变化,一直不知道这个是怎么做的,最近查了一些资料才发现有一个 visibilitychange 事件就可以搞定,这里将介绍一下页面可见性 ...

  3. GO开发[四]:golang函数

    函数 1.声明语法:func 函数名 (参数列表) [(返回值列表)] {} 2.golang函数特点: a. 不支持重载,一个包不能有两个名字一样的函数 b. 函数是一等公民,函数也是一种类型,一个 ...

  4. 基于C#的数据库文件管理助手

    我们经常会遇到这样的问题,在数据库中的文件存放的是web格式或者是绝对路径,以及使用的是百度上传或者其他上传组件,造成了很多异步上传的冗余文件,如果客户需要我们导出企业官网中的产品图片,我们该如何处理 ...

  5. 布隆(Bloom)过滤器 JAVA实现

    前言 Bloom过滤器,通过将字符串映射为信息指纹从而节省了空间.Bloom过滤器的原理为,将一个字符串通过一定算法映射为八个Hash值,将八个Hash值对应位置的Bitset位进行填充.在进行校验的 ...

  6. 20170723-Ioc与AOP

    Ioc与AOP 功能.语法.分类.原理.例子.补充(AOP-Ioc-DI) 1.AOP: ①功能体现:是拦截,过滤器: ②相关语法:借助特性语法作为切入点: ③实现方式分类:动态代理+静态织入: ④实 ...

  7. 自定义alert弹框

    /**************** UIAlertControllerStyleAlert *************************/ /*创建一个 可以自定义文字颜色和字体大小的IAler ...

  8. dede从www跟目录迁移,网站空间

    图集缩略图表名dede_uploads                    字段url; 图集文章内部的图片表名dede_addonimages        字段imgurls 频道文章列表的图片 ...

  9. SSL协议之数据加密过程详解

    前言 总括: 原文博客地址:SSL协议之数据加密过程详解 知乎专栏&&简书专题:前端进击者(知乎)&&前端进击者(简书) 博主博客地址:Damonare的个人博客 生活 ...

  10. 注解Responsebody RequestBody RequestMapping

    编写代码时候很容易遗漏注解,尤其比较重要的注解,调试很久也找不到原因,在处理页面请求异常时,如果后台正常,就是发现没有把想要的对象传到页面就注意下看注解是否缺失?例如:/** * @Author gj ...