题目描述

在2016年,佳媛姐姐刚刚学习了第二类斯特林数,非常开心。

现在他想计算这样一个函数的值:
S(i, j)表示第二类斯特林数,递推公式为:
S(i, j) = j ∗ S(i − 1, j) + S(i − 1, j − 1), 1 <= j <= i − 1。
边界条件为:S(i, i) = 1(0 <= i), S(i, 0) = 0(1 <= i)
你能帮帮他吗?

输入

输入只有一个正整数

输出

输出f(n)。由于结果会很大,输出f(n)对998244353(7 × 17 × 223 + 1)取模的结果即可。1 ≤ n ≤ 100000

样例输入

3


题解

NTT

考虑第二类斯特林数的公式:

(第二类斯特林数的含义是把n个数分成m个非空集合的方案数,考虑容斥,如果不考虑集合的无序性,至少有i个空集的方案数为$C_m^i*(m-i)^n$,除以$m!$后容斥一下,故有此式)

然后答案就是:

很容易发现后面的$\sum$是一个卷积的形式,设$f(x)=\frac{(-1)^x}{x!},g(x)=\frac{\sum\limits_{i=0}^nx^i}{x!}$,那么答案为$\sum\limits_{j=0}^nh(j)=\sum\limits_{j=0}^nf*g(j)$。

使用NTT加速求解,时间复杂度为$O(n\log n)$。

注意当首项为1时,等比数列求和公式不能使用,需要特判。

#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 300010
using namespace std;
typedef long long ll;
const ll mod = 998244353;
ll fac[N] , p[N] , a[N] , b[N];
ll pow(ll x , ll y)
{
ll ans = 1;
while(y)
{
if(y & 1) ans = ans * x % mod;
x = x * x % mod , y >>= 1;
}
return ans;
}
void ntt(ll *a , int len , int flag)
{
int i , j , k;
for(i = k = 0 ; i < len ; i ++ )
{
if(i > k) swap(a[i] , a[k]);
for(j = len >> 1 ; (k ^= j) < j ; j >>= 1);
}
for(k = 2 ; k <= len ; k <<= 1)
{
ll wn = pow(3 , (mod - 1) / k);
if(flag == -1) wn = pow(wn , mod - 2);
for(i = 0 ; i < len ; i += k)
{
ll w = 1 , t;
for(j = i ; j < i + (k >> 1) ; j ++ , w = w * wn % mod)
t = w * a[j + (k >> 1)] % mod , a[j + (k >> 1)] = (a[j] - t + mod) % mod , a[j] = (a[j] + t) % mod;
}
}
if(flag == -1)
{
k = pow(len , mod - 2);
for(i = 0 ; i < len ; i ++ ) a[i] = a[i] * k % mod;
}
}
int main()
{
int n , i , len = 1;
ll inv = 1 , ans = 0;
scanf("%d" , &n);
a[0] = b[0] = fac[0] = p[0] = 1;
for(i = 1 ; i <= n ; i ++ )
{
fac[i] = fac[i - 1] * i % mod , p[i] = p[i - 1] * 2 % mod;
inv = inv * pow(i , mod - 2) % mod;
if(i & 1) a[i] = mod - inv;
else a[i] = inv;
if(i == 1) b[i] = n + 1;
else b[i] = (pow(i , n + 1) - 1) * (pow(i - 1 , mod - 2)) % mod * inv % mod;
}
while(len <= 2 * n) len <<= 1;
ntt(a , len , 1) , ntt(b , len , 1);
for(i = 0 ; i < len ; i ++ ) a[i] = a[i] * b[i] % mod;
ntt(a , len , -1);
for(i = 0 ; i <= n ; i ++ ) ans = (ans + fac[i] * p[i] % mod * a[i]) % mod;
printf("%lld\n" , ans);
return 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. BZOJ 4555: [Tjoi2016&Heoi2016]求和 (NTT + 第二类斯特林数)

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

  6. 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 ...

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

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

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

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

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

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

随机推荐

  1. python __getattr__ __setattr__

    class Rectangle: def __init__(self): self.width = 0 self.height = 0 def __setattr__(self, key, value ...

  2. 2017.12.1 如何用java写出一个菱形图案

    上机课自己写的代码 两个图形原理都是一样的 1.一共有仨个循环 注意搞清楚每一层循环需要做的事情 2.第一层循环:是用来控制行数 3.第二层循环控制打印空格数 4.第三层循环是用来循环输出星星 imp ...

  3. js 数组方法大集合,各方法是否改变原有的数组详解

    不会改变原来数组的有: concat()---连接两个或更多的数组,并返回结果. every()---检测数组元素的每个元素是否都符合条件. some()---检测数组元素中是否有元素符合指定条件. ...

  4. InstallShield Limited Edition for Visual Studio 2013 图文教程打包安装包

    http://www.wuleba.com/23892.html 从Visual Studio 2012开始,微软就把自家原来的安装与部署工具彻底废掉了,转而让大家去安装使用第三方的打包工具“Inst ...

  5. c++ question 003 求两数大者?

    #include <iostream>using namespace std; int main(){ //求两数中的大者? int a,b; cin>>a>>b; ...

  6. SpringMVC URL模板模式映射

    使用@RequestMaping和@PathVariable 组合使用 通过 @PathVariable  可以将 URL 中占位符参数绑定到控制器处理方法的入参中:URL 中的 {xxx} 占位符可 ...

  7. Apache 查找httpd.conf文件

    Linux下查找httpd.conf文件 $ find / -name httpd.conf  

  8. Python_深浅拷贝

    深浅拷贝 ‘copy’和'='的区别:copy会开辟一个新的空间,而‘=’不会. 浅copy只会copy第一层,再里边的就进行共享了. 需要记住的是copy之后记住的是内存寻址地址,而浅copy时如果 ...

  9. 最新手机号正则表达式php包括166等号段

    if(!preg_match("/^((13[0-9])|(14[5,7])|(15[0-3,5-9])|(17[0,3,5-8])|(18[0-9])|166|198|199|(147)) ...

  10. 无线Web开发

    http://am-team.github.io/amg/dev-exp-doc.html