bzoj4555: 求和sum 快速傅立叶变换
题目大意
给定\(S(n,m)\)表示第二类斯特林数,定义函数\(f(n)\)
\[f(n) = \sum_{i=0}^n\sum_{j=0}^iS(i,j)*2^j*(j!)
\]给定正整数\(n,(n\leq 10^5)\),求\(f(n)\)
题解
我们都知道第二类斯特林数的递推公式为
\]
且有边界\(S(i,i) = 1(0 \leq i),S(i,0) = 0(1 \leq i)\)
第二类斯特林数\(S(i,j)\)的含义是把\(i\)个元素划分成\(j\)个无序的集合的方案
假设允许空集合的存在的话,方案即为\(m^n\)
我们应用容斥原理,枚举至少有多少空集合空集合,那么有
\]
设\(g(n) = \sum_{i=0}^nS(n,i)2^i(i!)\)
那么我们将\(S(n,m)\)代入\(g(n)\)化简得
\]
那么将\(g(n)\)带入答案表达式中,有
\]
这时我们发现每次最外层的\(n -> (n+1)\)时,都相当于在内部的\(\frac{(m-k)^n}{(m-k)!}\)一项上又加上了一个\(\frac{(m-k)^{n+1}}{(m-k)!}\)
所以我们把这一项做等比数列求和.
设\(g(x) = \frac{x^{n+1} - x}{(x-1)(x!)}\)
那么上式变成了
\]
于是我们在\(\sum_{k=0}^m\frac{(-1)^k}{k!}g(m-k)\)进行FFT计算卷积
这样就只剩下了一个sigma式,for循环一边即可.
复杂度\(O(nlogn)\)

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
template<typename T>inline void read(T &x){
	x=0;char ch;bool flag = false;
	while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true;
	while(x=10*x+ch-'0',ch=getchar(),ch>'!');if(flag) x=-x;
}
const int maxn = 600010;
const int mod = 998244353;
const int pri_rt = 3;
int w[maxn];
inline int qpow(int x,int p){
	int ret = 1;
	for(;p;p>>=1,x=1LL*x*x%mod) if(p&1) ret=1LL*ret*x % mod;
	return ret;
}
inline void FNT(int *x,int n,int p){
	for(int i=0,t=0;i<n;++i){
		if(i > t) swap(x[i],x[t]);
		for(int j=n>>1;(t^=j)<j;j>>=1);
	}
	for(int m=2;m<=n;m<<=1){
		int k = m>>1;
		int wn = qpow(pri_rt,p == 1 ? (mod-1)/m : (mod-1) - (mod-1)/m);
		for(int i=1;i<k;++i) w[i] = 1LL*w[i-1]*wn % mod;
		w[0] = 1;
		for(int i=0;i<n;i+=m){
			for(int j=0;j<k;++j){
				int u = 1LL*x[i+j+k]*w[j] % mod;
				x[i+j+k] = x[i+j] - u;
				if(x[i+j+k] < 0) x[i+j+k] += mod;
				x[i+j] += u;
				if(x[i+j] >= mod) x[i+j] -= mod;
			}
		}
	}
	if(p == -1){
		int inv = qpow(n,mod-2);
		for(int i=0;i<n;++i) x[i] = 1LL*x[i]*inv % mod;
	}
}
int fac[maxn],inv[maxn];
inline void init(int n){
	fac[0] = 1;
	for(int i=1;i<=n;++i) fac[i] = 1LL*fac[i-1]*i % mod;
	inv[n] = qpow(fac[n],mod-2);
	for(int i = n-1;i>=0;--i) inv[i] = 1LL*inv[i+1]*(i+1) % mod;
}
int A[maxn],B[maxn];
int main(){
	int n;read(n);
	int len;for(len=1;len <= (n+1);len<<=1);len<<=1;
	init(n);
	for(int i=0;i<=n;++i){
		if(i&1) A[i] = -inv[i] + mod;
		else A[i] = inv[i];
	}
	for(int i=2;i<=n;++i){
		B[i] = qpow(i,n+1) - i + mod;
		if(B[i] < 0) B[i] += mod;
		B[i] = (1LL*B[i]*qpow(i-1,mod-2)%mod*inv[i]) % mod;
	}B[1] = n;
	FNT(A,len,1);FNT(B,len,1);
	for(int i=0;i<len;++i) A[i] = 1LL*A[i]*B[i] % mod;
	FNT(A,len,-1);
	int ans = 1;
	for(int i=1,f2=2;i<=n;++i){
		ans = (ans + 1LL*A[i]*f2%mod*fac[i]) % mod;
		f2 = (f2<<1) % mod;
	}printf("%d\n",ans);
	getchar();getchar();
	return 0;
}
												
											bzoj4555: 求和sum 快速傅立叶变换的更多相关文章
- 离散傅立叶变换与快速傅立叶变换(DFT与FFT)
		
自从去年下半年接触三维重构以来,听得最多的词就是傅立叶变换,后来了解到这个变换在图像处理里面也是重点中的重点. 本身自己基于高数知识的理解是傅立叶变换是将一个函数变为一堆正余弦函数的和的变换.而图像处 ...
 - $\mathcal{FFT}$·$\mathcal{Fast \ \  Fourier  \ \ Transformation}$快速傅立叶变换
		
\(2019.2.18upd:\) \(LINK\) 之前写的比较适合未接触FFT的人阅读--但是有几个地方出了错,大家可以找一下233 啊-本来觉得这是个比较良心的算法没想到这么抽搐这个算法真是将一 ...
 - 快速傅立叶变换(FFT)
		
多项式 系数表示法 设\(f(x)\)为一个\(n-1\)次多项式,则 \(f(x)=\sum\limits_{i=0}^{n-1}a_i*x_i\) 其中\(a_i\)为\(f(x)\)的系数,用这 ...
 - BZOJ 2194 快速傅立叶变换之二 | FFT
		
BZOJ 2194 快速傅立叶变换之二 题意 给出两个长为\(n\)的数组\(a\)和\(b\),\(c_k = \sum_{i = k}^{n - 1} a[i] * b[i - k]\). 题解 ...
 - 为什么要进行傅立叶变换?傅立叶变换究竟有何意义?如何用Matlab实现快速傅立叶变换
		
写在最前面:本文是我阅读了多篇相关文章后对它们进行分析重组整合而得,绝大部分内容非我所原创.在此向多位原创作者致敬!!!一.傅立叶变换的由来关于傅立叶变换,无论是书本还是在网上可以很容易找到关于傅立叶 ...
 - 快速傅立叶变换(FFT)算法
		
已知多项式f(x)=a0+a1x+a2x2+...+am-1xm-1, g(x)=b0+b1x+b2x2+...+bn-1xn-1.利用卷积的蛮力算法,得到h(x)=f(x)g(x),这一过程的时间复 ...
 - NVIDIA GPU的快速傅立叶变换
		
NVIDIA GPU的快速傅立叶变换 cuFFT库提供GPU加速的FFT实现,其执行速度比仅CPU的替代方案快10倍.cuFFT用于构建跨学科的商业和研究应用程序,例如深度学习,计算机视觉,计算物理, ...
 - 傅立叶变换系列(五)快速傅立叶变换(FFT)
		
说明: 傅里叶级数.傅里叶变换.离散傅里叶变换.短时傅里叶变换...这些理解和应用都非常难,网上的文章有两个极端:“Esay” Or “Boring”!如果单独看一两篇文章就弄懂傅里叶,那说明你真 ...
 - [快速傅立叶变换&快速傅里叶变换]【旧 手写笔记】
		
$FFT$好美啊 参考资料: 1.算法导论 2.Miskcoo 3.Menci 4.虚数的意义-阮一峰 简单说一下,具体在下面的图片 实现: 可以用$complex$也可以手写 和计算几何差不多 注意 ...
 
随机推荐
- 15:取近似值ApproximateValue
			
题目描述 写出一个程序,接受一个正浮点数值,输出该数值的近似整数值.如果小数点后数值大于等于5,向上取整:小于5,则向下取整. 输入描述:输入一个正浮点数值 输出描述:输出该数值的近似整数值 输入例子 ...
 - 多域名THINKPHP利用MEMCACHE方式共享SESSION数据(转)
			
一.问题起源 稍大一些的网站,通常都会有好几个服务器,每个服务器运行着不同功能的模块,使用不同的二级域名,而一个整体性强的网站,用户系统是统一的,即一套用户名.密码在整个网站的各个模块中都是可以登录使 ...
 - C++第4次实验(提高班)—继承和派生1
			
从项目2和项目3中选1题作为实验.剩下2题写成作业. [项目1 - 龙三] 请在以下程序的横线处填上适当内容,以使程序完整,并使程序的输出为: Name: 龙三 Grade: 19 #include ...
 - 深入Asyncio(十二)Asyncio与单元测试
			
Testing with asyncio 之前有说过应用开发者不需要将loop当作参数在函数间传递,只需要调用asyncio.get_event_loop()即可获得.但是在写单元测试时,可能会需要用 ...
 - 机器学习三 -- 用Python实现K-近邻算法
			
Python语言实现机器学习的K-近邻算法 写在前面 额...最近开始学习机器学习嘛,网上找到一本关于机器学习的书籍,名字叫做<机器学习实战>.很巧的是,这本书里的算法是用Python语言 ...
 - ASP.NET RemoteAttribute远程验证更新问题
			
create时使用remote特性没有任何问题, update时,问题就大了,验证唯一性时需要排除自身,如果使用这个特性将无法正确的验证. 改进思路:将自动生成的标签属性改为手写,,并在url上面加上 ...
 - 怎样实现动态加入布局文件(避免 The specified child already has a parent的问题)
			
首先扯点别的:我应经连续上了两个星期的班了,今天星期一.是第三个周.这个班上的也是没谁了.近期老是腰疼. 预计是累了.近期也没跑步.今天下班继续跑起. 这篇文章讲一讲怎样在一个布局文件里动态加在一个布 ...
 - Windows系统下正确安装MongoDB
			
1.下载.安装 官网下载: http://www.mongodb.org/downloads 下载好之后,接下来进行安装了: 2.创建数据文件夹 MongoDB将数据文件夹存储在 db 文件夹下. 可 ...
 - 开发环境部署git 步骤
			
1.安装完后,打开git bash. vim .gitconfig 此文件放在用户目录,即 git bash 打开后默认位置. 2.插入以下内容,保存 [user] name = email = [ ...
 - NVR硬件录像机web无插件播放方案功能实现之相关接口注意事项说明
			
该篇博文主要用来说明EasyNVR硬件录像回放版本的相关接口说明和调用的demo: 方便用户的二次开发和集成. 软件根目录会包含接口文档的,因此,本文主要是对一些特定接口的说明和接口实现功能的讲解以及 ...