点此看题面

大致题意: 计算\(\sum_{i=0}^n\sum_{j=0}^iS(i,j)*2^j*(j!)\),其中\(S\)为第二类斯特林数。

推式子

首先让我们来推一波式子:

因为当\(i<j\)时,\(S(i,j)=0\),所以,为了方便式子的化简,我们可以先将第二个\(\sum\)的上限全部改成\(n\),即:

\[\sum_{i=0}^n\sum_{j=0}^nS(i,j)*2^j*(j!)
\]

这样一来,\(\sum_{j=0}^n2^j*(j!)\)这个式子就与\(i\)无关,则我们可以将其提前:

\[\sum_{j=0}^n2^j*(j!)\sum_{i=0}^nS(i,j)
\]

套用第二类斯特林数的通项公式\(S(n,m)=\sum_{i=0}^m\frac{(-1)^i*(m-i)^n}{i!(m-i)!}\)可以得到:

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

接下来,我们可以考虑再将所有与\(i\)无关的项提前,得到下面这个式子:

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

我们可以枚举\(j\),这样前面的\(\sum_{j=0}^n2^j*(j!)\)一项就可以轻松搞定。

那么接下来的问题就是如何对于给定的\(j\),求出下面这个式子的值:

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

仔细观察,可以发现似乎这个式子前半部分的分母和后半部分都有\((j-k)\)这个因式,则容易想到将它们移到一起,即:

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

这样一移的效果是显著的,因为此时这个式子的前半部分只与\(k\)有关,后半部分只与\((j-k)\)有关。

则可以设\(f\)和\(g\)如下:

\[f_x=\frac{(-1)^x}{x!}
\]

\[g_x=\sum_{i=0}^n\frac{x^i}{x!}=\frac{\sum_{i=0}^nx^i}{x!}=\frac{\frac{x^{n+1}-1}{x-1}}{x!}=\frac{x^{n+1}-1}{(x-1)x!}
\]

带入原式就可以得到:

\[\sum_{k=0}^jf_{k}*g_{j-k}
\]

而这个式子实际上就相当于:

\[(f*g)(j)
\]

至此化简完毕,最终的式子就是:

\[\sum_{j=0}^n2^j*(j!)*(f*g)(j)
\]

具体实现

我们可以先\(O(n)\)(\(O(nlogn)\)?)预处理出\(f\)和\(g\)两个数组,然后\(NTT\)即可。

这应该还是比较简单的吧。

代码

#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
#define N 100000
#define X 998244353
#define Qinv(x) (Qpow(x,X-2))
#define swap(x,y) (x^=y^=x^=y)
#define Inc(x,y) ((x+=(y))>=X&&(x-=X))
#define XSum(x,y) ((x)+(y)>=X?(x)+(y)-X:(x)+(y))
#define XSub(x,y) ((x)-(y)<0?(x)-(y)+X:(x)-(y))
using namespace std;
int n,a[(N<<2)+5],b[(N<<2)+5],Fac[N+5],Inv[N+5];
I int Qpow(RI x,RI y) {RI res=1;W(y) y&1&&(res=1LL*res*x%X),x=1LL*x*x%X,y>>=1;return res;}
class NTT//NTT求模意义下的卷积
{
private:
static const int SZ=N,PR=3,IP=(X+1)/3;int P,L,R[(SZ<<2)+5];
I void Transform(int* s,CI op)
{
RI i,j,k,U,S,tx,ty;for(i=0;i^P;++i) i<R[i]&&swap(s[i],s[R[i]]);
for(i=1;i^P;i<<=1) for(U=Qpow(~op?PR:IP,(X-1)/(i<<1)),j=0;j^P;j+=(i<<1))
for(S=1,k=0;k^i;++k,S=1LL*S*U%X) tx=s[j+k],ty=1LL*S*s[i+j+k]%X,s[j+k]=XSum(tx,ty),s[i+j+k]=XSub(tx,ty);
}
public:
I void Solve(CI n,CI m,int* a,int* b)
{
RI i,t;P=1,L=0,memset(R,0,sizeof(R));
W(P<=n+m) P<<=1,++L;for(i=0;i^P;++i) R[i]=(R[i>>1]>>1)|((i&1)<<L-1);
for(Transform(a,1),Transform(b,1),i=0;i^P;++i) a[i]=1LL*a[i]*b[i]%X;
for(Transform(a,-1),t=Qinv(P),i=0;i<=n+m;++i) a[i]=1LL*a[i]*t%X;
}
}NTT;
int main()
{
RI i,t,ans=0;for(scanf("%d",&n),Fac[0]=1,i=1;i<=n;++i) Fac[i]=1LL*Fac[i-1]*i%X;//预处理阶乘
for(Inv[n]=Qpow(Fac[n],X-2),i=n-1;~i;--i) Inv[i]=1LL*Inv[i+1]*(i+1)%X;//预处理阶乘的逆元
for(t=1,i=0;i<=n;++i,t=1LL*t*(X-1)%X) a[i]=1LL*t*Inv[i]%X;//预处理第一个数组
for(b[0]=1,b[1]=n+1,i=2;i<=n;++i) b[i]=1LL*(Qpow(i,n+1)-1)*Qinv(i-1)%X*Inv[i]%X;//预处理第二个数组
for(NTT.Solve(n,n,a,b),t=1,i=0;i<=n;++i,(t<<=1)>=X&&(t-=X)) Inc(ans,1LL*a[i]*t%X*Fac[i]%X);//做一遍NTT,然后统计答案
return printf("%d",ans),0;//输出答案
}

【BZOJ4555】[TJOI2016&HEOI2016] 求和(NTT)的更多相关文章

  1. [BZOJ4555 TJOI2016 HEOI2016 求和]

    ​ 第一篇博客,请大家多多关照.(鞠躬 BZOJ4555 TJOI2016 HEOI2016 求和 题意: ​ 给定一个正整数\(n\)(\(1\leqq n \leqq100000\)),求: \[ ...

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

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

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

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

  4. 【bzoj4555】[Tjoi2016&Heoi2016]求和 NTT

    题目描述 在2016年,佳媛姐姐刚刚学习了第二类斯特林数,非常开心. 现在他想计算这样一个函数的值: S(i, j)表示第二类斯特林数,递推公式为: S(i, j) = j ∗ S(i − 1, j) ...

  5. BZOJ4555 [Tjoi2016&Heoi2016]求和 【第二类斯特林数 + NTT】

    题目 在2016年,佳媛姐姐刚刚学习了第二类斯特林数,非常开心. 现在他想计算这样一个函数的值: S(i, j)表示第二类斯特林数,递推公式为: S(i, j) = j ∗ S(i − 1, j) + ...

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

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

  7. Bzoj4555: [Tjoi2016&Heoi2016]求和

    题面 Bzoj Sol 推柿子 因为当\(j>i\)时\(S(i, j)=0\),所以有 \[\sum_{i=0}^{n}\sum_{j=0}^{n}S(i, j)2^j(j!)\] 枚举\(j ...

  8. bzoj 4555 [Tjoi2016&Heoi2016]求和——NTT+第二类斯特林数

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4555 第二类斯特林数展开式: \( S(i,j) = \frac{1}{j!} \sum\l ...

  9. 【BZOJ】4555: [Tjoi2016&Heoi2016]求和 排列组合+多项式求逆 或 斯特林数+NTT

    [题意]给定n,求Σi=0~nΣj=1~i s(i,j)*2^j*j!,n<=10^5. [算法]生成函数+排列组合+多项式求逆 [题解]参考: [BZOJ4555][Tjoi2016& ...

  10. 【BZOJ 4555】 4555: [Tjoi2016&Heoi2016]求和 (NTT)

    4555: [Tjoi2016&Heoi2016]求和 Time Limit: 40 Sec  Memory Limit: 128 MBSubmit: 315  Solved: 252 Des ...

随机推荐

  1. 19. Remove Nth Node From End of List(C++,Python)

    Given a linked list, remove the nth node from the end of list and return its head. For example, Give ...

  2. Problem06 求最大公约数及最小公倍数

    题目:输入两个正整数m和n,求其最大公约数(m,n)和最小公倍数[m,n]. 程序分析:利用辗转相除法. 利用辗除法:用较大数除以较小数,再用出现的余数(第一余数)去除除数, 再用出现的余数(第二余数 ...

  3. Maven使用之packing篇

    项目的打包类型:pom.jar.war 项目中一般使用maven进行模块管理,每个模块下对应都有一个pom文件,pom文件中维护了各模块之间的依赖和继承关系.项目模块化可以将通用的部分抽离出来,方便重 ...

  4. 性能测试工具LoadRunner18-LR之Controller 集合点

    含义 当通过controller虚拟多个用户执行该脚本时.用户的启动或运行步骤不一定是同步的.集合点是在脚本的某处设置一个标记.当有虚拟用户运行到这个标记时,停下等待,直到所有用户都达到这个标记时,再 ...

  5. 性能测试工具LoadRunner03-LR之Virtual User Generator 脚本创建以及回放设置

    vuser_init,Action,vuser_end说明 vuser_init 录制的一般是业务流程开始之前的初始化工作(如登录,服务器初始化) Action 录制的一般是业务流程操作的事件 vus ...

  6. Java集合框架概述

    集合框架指的是容器类.Java中大量持有对象的方式有数组和容器类两种方式.数组相较于容器类的优点在于:①随机访问效率高:由于是连续的存储空间,可以计算地址直接访问 ②类型确定:数组在创建时即可确定元素 ...

  7. php错误等级

    E_ALL - 所有的错误和警告(不包括 E_STRICT)   E_ERROR - 致命性的运行时错误   E_WARNING - 运行时警告(非致命性错误)   E_PARSE - 编译时解析错误 ...

  8. logback.xml日志文件过滤器配置简析

    自定义过滤器 java代码,目的是在mdc中放值,然后在日志中打印 package com.controller; import com.pojo.JsonData; import org.slf4j ...

  9. 根据tomcat日志查找想要的错误日志

    1.首先要记得程序报的错误信息 我的错误信息是[2015接收的参数中有空值],对应程序中的返回值是2015 以及出现错误信息的大致时间,我的大概是吃过午饭后,12:40-13:20之间 2.先去log ...

  10. JavaScript new 操作符 OOP(一)

    什么是对象    对象是单个实物的抽象,通常需要一个模板,表示某一类实物的共同特征,然后对象根据这个模板生成. 对象是一个容器,封装了属性(property)和方法(method),属性是对象的状态, ...