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是第二类斯特林数
***
首先你要把这个组合计数肝出来,~~于是我去翻了一波《组合数学》~~
*用斯特林数容斥原理推导那个式子可以直接出卷积形式,见下一篇,本篇是分治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)!}
</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 组合计数 | 多项式求逆]的更多相关文章
- BZOJ 4555 [Tjoi2016&Heoi2016]求和 ——分治 NTT 多项式求逆
不想多说了,看网上的题解吧,我大概说下思路. 首先考察Stirling的意义,然后求出递推式,变成卷积的形式. 然后发现贡献是一定的,我们可以分治+NTT. 也可以直接求逆(我不会啊啊啊啊啊) #in ...
- 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是第二类斯特林 ...
- [BZOJ4555][TJOI2016&HEOI2016]求和(分治FFT)
4555: [Tjoi2016&Heoi2016]求和 Time Limit: 40 Sec Memory Limit: 128 MBSubmit: 525 Solved: 418[Sub ...
- bzoj 4555 [Tjoi2016&Heoi2016]求和 NTT 第二类斯特林数 等比数列求和优化
[Tjoi2016&Heoi2016]求和 Time Limit: 40 Sec Memory Limit: 128 MBSubmit: 679 Solved: 534[Submit][S ...
- BZOJ 4555 [Tjoi2016&Heoi2016]求和 (多项式求逆)
题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=4555 题目大意: 给定 \(S(n,m)\) 表示第二类斯特林数,定义函数 \(f(n ...
- 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 ...
- 洛谷P4721 【模板】分治 FFT(生成函数+多项式求逆)
传送门 我是用多项式求逆做的因为分治FFT看不懂…… upd:分治FFT的看这里 话说这个万恶的生成函数到底是什么东西…… 我们令$F(x)=\sum_{i=0}^\infty f_ix^i,G(x) ...
- [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 ...
- BZOJ 4555: [Tjoi2016&Heoi2016]求和 (NTT + 第二类斯特林数)
题意 给你一个数 \(n\) 求这样一个函数的值 : \[\displaystyle f(n)=\sum_{i=0}^{n}\sum_{j=0}^{i} \begin{Bmatrix} i \\ j ...
随机推荐
- thinkphp5使用redis实现秒杀商品活动
如题,废话少说贴码为上↓ // 初始化redis数据列表 模拟库存50,redis搭建在centos中已开启 public function redisinit(){ $store=50; // 库存 ...
- TP5使用phpmailer实现邮件发送
1.从github下载PHPMailer,在vendor目录中新建文件夹phpmailer,将压缩包中的class.phpmailer.php和class.smtp.php复制到phpmailer中, ...
- PHP编码规范及建议
<h3 align="center">PHP编码规范及建议</h3>### 编码规范- PHP代码文件必须以 <?php 标签开始.```<?p ...
- asp.net -mvc框架复习(2)-创建ASP.NET MVC 第一个程序以及MVC项目文件夹说明
建议vs2013或2013以上版本的vs,要是跨平台的话最好用vs2015或vs2017的asp.net mvc core . 1.创建ASP.NET MVC 第一个程序 打开vs2013->文 ...
- Android知识点剖析系列:深入了解layout_weight属性
摘录自:http://www.cnblogs.com/net168/p/4227144.html 前言 Android中layout_weight这个属性对于经常捣鼓UI的我们来说,肯定不会陌生.但是 ...
- 1.MAVEN项目的创建与问题的解决
一.创建一个maven-webapp.(环境:mac和15版本的IDEA) 二.next--->填写groupId(公司单位的名字,你组织的名字)和ArtifactID(有关tomcat,以后用 ...
- P2045 方格取数加强版
P2045 方格取数加强版 题目描述 给出一个n*n的矩阵,每一格有一个非负整数Aij,(Aij <= 1000)现在从(1,1)出发,可以往右或者往下走,最后到达(n,n),每达到一格,把该格 ...
- AMS的适用场景
AMS适用于网络音视频应用的各种场合,可以独立作为直播点播平台应用,也可以嵌入到用户的各种应用平台中,为客户提供音视频核心支撑,不同于其它提供云服务租给客户使用的产品,AMS是一套安装在企业内部服务器 ...
- org.apache.catalina.util.DefaultAnnotationProcessor cannot be cast to org.apache.AnnotationProcessor
这几天来公司,公司的SVN坏掉了,然后项目还比较大,是一个分布式的,然后同事就把项目发我了.我在myeclipse里面导入项目了,把相应的jar包也建了个人的library导入了项目,现在项目不报错了 ...
- jsp小结
JSP执行步骤 完整步骤: 第一步:用户通过浏览器发出一个Http请求: 第二步:web服务器识别是对jsp页面的请求: 第三步:jsp容器通过jsp引擎将jsp页面转化为servlet代码(纯ja ...