伯努利数学习笔记&&Luogu P3711 仓鼠的数学题
新科技
题意
设$ S_{k,n}$表示$ \displaystyle\sum_{i=0}^n i^k$
求多项式$\displaystyle\sum_{k=0}^n S_{k,x}a_k$的各项系数
数组$ a$给定,$ n \leq 100000$
伯努利数
伯努利数$B$是一个数列,满足
$$\sum_{i=0}^n B_i\binom{n+1}{i}=0$$
可以用它来求自然数幂和
$$ S_{k,n-1}=\sum_{i=0}^{n-1}i^k=\frac{1}{k+1}\sum_{i=0}^k\binom{k+1}{i}B_in^{k+1-i}$$
如果已经得到了数列$ B$,求自然数幂和$S_{k,n}$是$ O(k)$的
直接根据定义可以$ O(n^2)$递推伯努利数,考虑更快速的推法
$$
\begin{aligned}
\sum_{i=0}^n B_i\binom{n+1}{i}&=0\\
\sum_{i=0}^{n-1} B_i\binom{n}{i}&=0 \ (n>1)\\
B_n+\sum_{i=0}^{n-1} B_i\binom{n}{i}&=B_n \ (n>1)\\
B_n&=\sum_{i=0}^nB_i\binom{n}{i} \ (n>1)\\
\frac{B_n}{n!}&=\sum_{i=0}^n\frac{B_i}{i!(n-i)!}\\
\end{aligned}
$$
设伯努利数的指数型生成函数为$ B$,伯努利数的第一项$ B_1=-\frac{1}{2}$
则有$B*e^x=B+x$
整理得$B=\frac{x}{e^x-1}=(\frac{e^x-1}{x})^{-1}$
直接多项式求逆即可
时间复杂度$ O(n \log n)$
回到原题
用伯努利数展开得
$$
\begin{aligned}
ans&=\sum_{k=0}^na_k S_{k,x}\\
&=\sum_{k=0}^na_k(x^k+\frac{1}{k+1}\sum_{i=0}^k\binom{k+1}{i}B_ix^{k+1-i})\\
&=(\sum_{k=0}^na_kx^k)+(\sum_{k=0}^nk!\sum_{i=0}^k\frac{B_i}{i!(k+1-i)!}x^{k+1-i})\\
ans[x^d]&=a_d+\sum_{i=0}^{n+1}\frac{B_i}{d!i!}(d+i-1)!\\
\frac{ans[x^d]}{d!}&=a_d+\sum_{i=0}^{n+1}\frac{B_i}{i!}(d+i-1)!
\end{aligned}
$$
发现这是一个差卷积的形式
按套路反转之后$ NTT$即可
总复杂度仍是$ O(n \log n)$
代码
#include<ctime>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
#define p 998244353
#define rt register int
#define ll long long
#define ull unsigned long long
using namespace std;
inline ll read(){
ll x=;char zf=;char ch=getchar();
while(ch!='-'&&!isdigit(ch))ch=getchar();
if(ch=='-')zf=-,ch=getchar();
while(isdigit(ch))x=x*+ch-'',ch=getchar();return x*zf;
}
void write(ll y){if(y<)putchar('-'),y=-y;if(y>)write(y/);putchar(y%+);}
void writeln(const ll y){write(y);putchar('\n');}
int k,m,n,x,y,z,cnt,ans; namespace Poly{
#define poly vector<int>
#define MAXN 524288
int ksm(int x,int y=p-){
int ans=;
for(;y;y>>=,x=1ll*x*x%p)if(y&)ans=1ll*ans*x%p;
return ans;
}
void NTT(int n,poly &A,int fla){
static ull F[MAXN],W[MAXN];A.resize(n);
for(rt i=,j=;i<n;i++){
F[i]=A[j];
for(rt k=n>>;(j^=k)<k;k>>=);
}
for(rt i=;i<n;i<<=){
const int w=W[]=ksm(,(p-)//i);W[]=;
for(rt k=;k<i;k++)W[k]=1ll*W[k-]*w%p;
for(rt j=;j<n;j+=i<<){
for(rt k=;k<i;k++){
const ull x=F[j+k],y=F[i+j+k]*W[k]%p;
F[j+k]=x+y,F[i+j+k]=x+p-y;
}
}
}
for(rt i=;i<n;i++)A[i]=F[i]%p;
if(fla==-){
const int invn=ksm(n);
reverse(A.begin()+,A.end());
for(rt i=;i<n;i++)A[i]=1ll*A[i]*invn%p;
}
}
poly Mul(poly x,poly y){
int sz=x.size()+y.size()-,lim=;
while(lim<=sz)lim<<=;
NTT(lim,x,);NTT(lim,y,);
for(rt i=;i<lim;i++)x[i]=1ll*x[i]*y[i]%p;
NTT(lim,x,-);x.resize(sz);return x;
}
poly Inv(poly a,int n=-){
if(n==-)n=a.size();
if(n==)return {ksm(a[])};
poly c=Inv(a,n+>>),d(&a[],&a[n]);
int lim=;while(lim<=n*)lim<<=;
NTT(lim,c,);NTT(lim,d,);
for(rt i=;i<lim;i++)c[i]=1ll*c[i]*(2ll+p-1ll*d[i]*c[i]%p)%p;
NTT(lim,c,-);c.resize(n);return c;
}
}
using namespace Poly;
int inv[],jc[],njc[],a[];
poly B;
void init(int k){
for(rt i=;i<=;i++)inv[i]=jc[i]=njc[i]=;
for(rt i=;i<=k+;i++){
inv[i]=1ll*inv[p%i]*(p-p/i)%p;
jc[i]=1ll*jc[i-]*i%p;
njc[i]=1ll*njc[i-]*inv[i]%p;
}
B.resize(k+);
for(rt i=;i<=k;i++)B[i]=njc[i+];
B=Inv(B);
for(rt i=;i<=k;i++)B[i]=1ll*B[i]*jc[i]%p;
}
int main(){
n=read();init(n+);
for(rt i=;i<=n;i++)a[i]=read();
poly ans(n+),C(n+);
for(rt i=;i<=n;i++)B[i]=1ll*B[i]*njc[i]%p;
for(rt i=;i<=n;i++)C[i]=1ll*jc[i]*a[i]%p;
reverse(&B[],&B[n+]);B.resize(n+);C.resize(n+);
ans=Mul(B,C);
for(rt i=;i<=n+;i++)ans[n+i-]=1ll*ans[n+i-]*njc[i]%p;
for(rt i=;i<=n;i++)(ans[n+i-]+=a[i])%=p;write(a[]),putchar(' ');
for(rt i=;i<=n+;i++)write(ans[n+i-]),putchar(' ');
return ;
}
伯努利数学习笔记&&Luogu P3711 仓鼠的数学题的更多相关文章
- 洛谷 P3711 仓鼠的数学题 [伯努利数 fft]
P3711 仓鼠的数学题 题意: \[ S_m(x) = \sum_{k=0}^x k^m, 0^0=1\quad 求 \sum_{m=0}^n S_m(x)a_m \] 的答案多项式\(\sum_{ ...
- 洛谷 P3711 仓鼠的数学题【伯努利数+多项式科技】
有个东西叫伯努利数--一开始直接·用第一类斯特林推到自闭 式子来源:https://www.luogu.org/blog/ShadowassIIXVIIIIV/solution-p3711 https ...
- 洛谷P3711 仓鼠的数学题(伯努利数+多项式求逆)
题面 传送门 题解 如果您不知道伯努利数是什么可以去看看这篇文章 首先我们把自然数幂和化成伯努利数的形式 \[\sum_{i=1}^{n-1}i^k={1\over k+1}\sum_{i=0}^k{ ...
- 最小费用最大流 学习笔记&&Luogu P3381 【模板】最小费用最大流
题目描述 给出一个网络图,以及其源点和汇点,每条边已知其最大流量和单位流量费用,求出其网络最大流和在最大流情况下的最小费用. 题目链接 思路 最大流是没有问题的,关键是同时保证最小费用,因此,就可以把 ...
- 洛谷 P3711 - 仓鼠的数学题(多项式)
洛谷题面传送门 提供一种不太一样的做法. 假设要求的多项式为 \(f(x)\).我们考察 \(f(x)-f(x-1)\),不难发现其等于 \(\sum\limits_{i=0}^na_ix^i\) 考 ...
- Miller_Rabbin&&Pollard_Rho 学习笔记
占坑,待填 I Intro 首先我们考虑这样一个问题 给定一个正整数\(p(p<=1e8)\),请判断它是不是质数 妈妈我会试除法! 于是,我们枚举$ \sqrt p$ 以内的所有数,就可以非常 ...
- [P1169] 棋盘制作 &悬线法学习笔记
学习笔记 悬线法 最大子矩阵问题: 在一个给定的矩形中有一些障碍点,找出内部不包含障碍点的,边与整个矩形平行或重合的最大子矩形. 极大子矩型:无法再向外拓展的有效子矩形 最大子矩型:最大的一个有效子矩 ...
- 树上启发式合并(dsu on tree)学习笔记
有丶难,学到自闭 参考的文章: zcysky:[学习笔记]dsu on tree Arpa:[Tutorial] Sack (dsu on tree) 先康一康模板题吧:CF 600E($Lomsat ...
- DirectX 11游戏编程学习笔记之6: 第5章The Rendering Pipeline(渲染管线)
本文由哈利_蜘蛛侠原创,转载请注明出处.有问题欢迎联系2024958085@qq.com 注:我给的电子版是700多页,而实体书是800多页,所以我在提到相关概念的时候 ...
随机推荐
- 修改rpm中的文件重新打包
1.安装rpmrebuild 和安装rpmbuild rpmrebuild下载链接:https://sourceforge.net/projects/rpmrebuild/files/rpmrebui ...
- [已解决]ValueError: row index was 65536, not allowed by .xls format
报错: ValueError: row index was 65536, not allowed by .xls format 解决方案: xlrd和xlwt处理的是xls文件,单个sheet最大行数 ...
- python学习——读取染色体长度(三、用循环或者函数求总长并获取最长染色体长度)
# 读取fasta # 解析每条序列的长度 chr_len = [10,20,30,40,50] # 求和 # 方法一:通过循环 total_len = 0 #定义total_len的初始长度 for ...
- 关于当前Web前端技术的一些感悟和笔记
最近这些年,随着前端应用技术突飞猛进,产生了很多新的前端框架,当然也引入了数不胜数的前端技术概念,前端不在是早期Web Form的拖拉处理方式,也不再是Ajax+HTML那么简单,随着前端技术的发展, ...
- 随心测试_软测基础_001<说在开始_测试理念>
- 类Date
概述: java.util.Date类 表示特定的瞬间,精确到毫秒.毫秒就是千分之一秒.继续查阅API,发现Date拥有多个构造函数,只是部分已经过时,但是其中有未过时的构造函数可以把毫秒值转成日期对 ...
- 认识 CXF(WebService框架)
Apache CXF = Celtix + Xfire 支持多种协议: 1)SOAP1.1,1.2 2)HTTP 3)CORBA(Common Object Request Broker Archit ...
- 熟悉常用的HDFS操作
编程实现以下指定功能,并利用Hadoop提供的Shell命令完成相同任务: 在本地Linux文件系统的“/home/hadoop/”目录下创建一个文件txt,里面可以随意输入一些单词. 在本地查看文件 ...
- let 和 const 在for 循环中的使用
在ES6 的规范中,多了两个声明变量的关键字: let 和const.初次学习的时候,只记住了 let 声明的变量只在for 的循环体中有效,循环结束后 变量就消失了, 同时const 也可以在for ...
- hihoCoder #1954 : 压缩树(虚树)
题意 有一棵 \(n\) 个节点且以 \(1\) 为根的树,把它复制成 \(m\) 个版本,有 \(q\) 次操作,每次对 \([l, r]\) 这些版本的 \(v\) 节点到根的路径收缩起来. 收缩 ...