传送门

题意:

求

\[f(n)=\sum_{i=0}^n\sum_{j=0}^i\begin{Bmatrix}
i \\ j
\end{Bmatrix}2^jj!
\]

思路:

直接将第二类斯特林数展开有:

\[\begin{aligned}
f(n)=&\sum_{i=0}^n\sum_{j=0}^n2^j\sum_{k=0}^{j}(-1)^k{j\choose k}(j-k)^{i}\\
=&\sum_{i=0}^n\sum_{j=0}^n2^jj!\sum_{k=0}^j\frac{(-1)^k}{k!}\frac{(j-k)^i}{(j-k)!}\\
=&\sum_{j=0}^n2^jj!\sum_{k=0}^j\frac{(-1)^k}{k!}\frac{\sum_{i=0}^n(j-k)^i}{(j-k)!}
\end{aligned}
\]

观察到后半部分为一个卷积的形式,我们令\(\displaystyle a_i=\frac{(-1)^i}{i!},b_i=\frac{\sum_{j=0}^ni^j}{i!}\),其中\(\sum_{j=0}^n i^j\)为等比数列求和的形式。那么直接将这两个作为系数卷一卷即可。

还有一种做法为展开递推式的做法,忘了怎么做了。。明天来补。

upd:做法如下:

\[\begin{aligned}
f(n)=\sum_{j=0}^n2^jj!\sum_{i=j}^n\begin{Bmatrix}
i \\ j
\end{Bmatrix}
\end{aligned}
\]

令\(\displaystyle F(j)=\sum_{i=j}^n\begin{Bmatrix}
i \\ j
\end{Bmatrix}\),之后将第二类斯特林数用递推式展开:

\[\begin{aligned}
F(j)=&\sum_{i=j}^n\begin{Bmatrix}
i \\ j
\end{Bmatrix}\\
=&\sum_{i=j}^n\begin{Bmatrix}
i - 1 \\ j - 1
\end{Bmatrix}+\sum_{i=j}^nj\begin{Bmatrix}
i - 1 \\ j
\end{Bmatrix}\\
=&F(j-1)-\begin{Bmatrix}
n \\ j - 1
\end{Bmatrix}+jF(j)-j\begin{Bmatrix}
n \\ j
\end{Bmatrix}\\
=&F(j - 1)+jF(j)-\begin{Bmatrix}
n + 1 \\ j
\end{Bmatrix}
\end{aligned}
\]

所以最后有:

\[F(j)=\frac{F(j-1)-\begin{Bmatrix}
n + 1 \\ j
\end{Bmatrix}}{1-j}
\]

那么预处理出\(n+1\)这一行的斯特林数,然后直接用递推式算出\(F\)即可。

代码是第二种方法:

/*
* Author: heyuhhh
* Created Time: 2019/12/12 11:16:54
*/
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#define MP make_pair
#define fi first
#define se second
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
#define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
void err() { std::cout << '\n'; }
template<typename T, typename...Args>
void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
#else
#define dbg(...)
#endif
void pt() {std::cout << '\n'; }
template<typename T, typename...Args>
void pt(T a, Args...args) {std::cout << a << ' '; pt(args...); }
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 4e5 + 5, M = 2e6 + 5, P = 998244353, G = 3, Gi = 332748118, MOD = 998244353;
int n, m, lim = 1, L, r[N];
ll a[N], b[N];//注意空间要开四倍
ll qpow(ll a, ll k) {
ll ans = 1;
while(k) {
if(k & 1) ans = (ans * a ) % P;
a = (a * a) % P;
k >>= 1;
}
return ans;
}
void NTT(ll *A, int type) {
for(int i = 0; i < lim; i++)
if(i < r[i]) swap(A[i], A[r[i]]);
for(int mid = 1; mid < lim; mid <<= 1) {
ll Wn = qpow( type == 1 ? G : Gi , (P - 1) / (mid << 1)); //Wn = g ^ ((p - 1) / n) (mod p)
for(int j = 0; j < lim; j += (mid << 1)) {
ll w = 1;
for(int k = 0; k < mid; k++, w = (w * Wn) % P) {
int x = A[j + k], y = w * A[j + k + mid] % P;
A[j + k] = (x + y) % P,
A[j + k + mid] = (x - y + P) % P;
}
}
}
}
void solve(ll *a, ll *b) {
while(lim <= n + m) lim <<= 1, L++;
for(int i = 0; i < lim; i++) r[i] = (r[i >> 1] >> 1) | ((i & 1) << (L - 1));
for(int i = m + 1; i < lim; i++) a[i] = 0; //a,b need init
for(int i = m + 1; i < lim; i++) b[i] = 0;
NTT(a, 1); NTT(b, 1);
for(int i = 0; i < lim; i++) a[i] = (a[i] * b[i]) % P;
NTT(a, -1);
ll inv = qpow(lim, P - 2);
for(int i = 0; i < lim; i++) a[i] = a[i] * inv % P;
} int fac[N], inv[N], f[N], two[N]; void init() {
fac[0] = 1;
for(int i = 1; i < N; i++) fac[i] = 1ll * fac[i - 1] * i % MOD;
inv[N - 1] = qpow(fac[N - 1], MOD - 2);
for(int i = N - 2; i >= 0; i--) inv[i] = 1ll * inv[i + 1] * (i + 1) % MOD;
for(int i = 0; i <= m; i++) {
a[i] = (i & 1) ? MOD - inv[i] : inv[i];
b[i] = 1ll * qpow(i, n + 1) * inv[i] % MOD;
}
solve(a, b);
f[1] = n;
for(int i = 2; i <= n; i++) f[i] = 1ll * (a[i] - f[i - 1] + MOD) % MOD * qpow(i - 1, MOD - 2) % MOD;
two[0] = 1;
for(int i = 1; i <= n; i++) two[i] = 1ll * two[i - 1] * 2 % MOD;
} void run(){
cin >> n; m = n + 1;
init();
int ans = 1;
for(int i = 1; i <= n; i++) {
ans = (ans + 1ll * two[i] * fac[i] % MOD * f[i] % MOD) % MOD;
}
cout << ans << '\n';
} int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(20);
run();
return 0;
}

【bzoj4555】[Tjoi2016&Heoi2016]求和(NTT+第二类斯特林数)的更多相关文章

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

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

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

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

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

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

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

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

  5. 【BZOJ4555】求和(第二类斯特林数,组合数学,NTT)

    [BZOJ4555]求和(第二类斯特林数,组合数学,NTT) 题面 BZOJ 题解 推推柿子 \[\sum_{i=0}^n\sum_{j=0}^iS(i,j)·j!·2^j\] \[=\sum_{i= ...

  6. 【BZOJ4555】【TJOI2016】【HEOI2016】求和 (第二类斯特林数+NTT卷积)

    Description 在2016年,佳媛姐姐刚刚学习了第二类斯特林数,非常开心. 现在他想计算这样一个函数的值: $$f(n)=\sum_{i=0}^n\sum_{j=0}^i S(i,j)\tim ...

  7. 【BZOJ 4555】[Tjoi2016&Heoi2016]求和 多项式求逆/NTT+第二类斯特林数

    出处0.0用到第二类斯特林数的性质,做法好像很多,我打的是直接ntt,由第二类斯特林数的容斥公式可以推出,我们可以对于每一个i,来一次ntt求出他与所有j组成的第二类斯特林数的值,这个时候我们是O(n ...

  8. P4091 [HEOI2016/TJOI2016]求和(第二类斯特林数+NTT)

    传送门 首先,因为在\(j>i\)的时候有\(S(i,j)=0\),所以原式可以写成\[Ans=\sum_{i=0}^n\sum_{j=0}^nS(i,j)\times 2^j\times j! ...

  9. bzoj 5093 [Lydsy1711月赛]图的价值 NTT+第二类斯特林数

    [Lydsy1711月赛]图的价值 Time Limit: 30 Sec  Memory Limit: 256 MBSubmit: 245  Solved: 128[Submit][Status][D ...

随机推荐

  1. PlantUML Viewer Chrome 插件 画时序图

    PlantUML通过简单直观的语言来定义示意图 使用 Chrome+ PlantUML Viewer的插件画图 1,打开chrome网上应用店 2,搜索plantuml viewer 并添加 3,扩展 ...

  2. ARTS-S sed替换

    网上有大量替换的例子,比如 sed 's/aaa/bbb/g' a.txt 其实分隔符可以用别的字符,比如#,所以下面的命令也是正确的 sed 's#aaa#bbb#g' a.txt 用#号在用环境变 ...

  3. 笔记||Python3之面向对象

    面向对象编程:简称OOP. 是一种程序设计思想.oop把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数. 在python中,所有数据类型都可以视为对象,也可以自定义对象.自定义的对象数据类 ...

  4. 直击面试,聊聊 GC 机制

    前言 文章来源:https://studyidea.cn/ GC 中文直译垃圾回收,是一种回收内存空间避免内存泄漏的机制.当 JVM 内存紧张,通过执行 GC 有效回收内存,转而分配给新对象从而实现内 ...

  5. 【Flutter】372- Flutter移动端实战手册

    ☝点击上方蓝字,关注我们! 本文字数:3705字 预计阅读时间:28分钟 导 读 Flutter又双叒叕来了!本周推送是我们Flutter系列文章的最终篇!<Flutter移动端实战手册> ...

  6. 【重温基础】15.JS对象介绍

    从这篇文章开始,复习 MDN 中级教程 的内容了,在初级教程中,我和大家分享了一些比较简单基础的知识点,并放在我的 [Cute-JavaScript]系列文章中. 关于[Cute-JavaScript ...

  7. chrome 浏览器的使用技巧

    前端工程师大部分的工作成果都需要在浏览器中查看,使用 chrome 浏览器的频率非常高.更好更优雅地使用 chrome,将 chrome 配置成一款趁手的浏览器,将极大地提升编程效率.本文将详细介绍 ...

  8. UWP GraphQL数据查询的实现

    1. 缘起 Facebook 的移动应用从 2012 年就开始使用 GraphQL.GraphQL 规范于 2015 年开源,现已经在多种环境下可用,并被各种体量的团队所使用. 在这个链接可以看到更多 ...

  9. 《Java基础知识》Java数据类型以及变量的定义

    Java 是一种强类型的语言,声明变量时必须指明数据类型.变量(variable)的值占据一定的内存空间.不同类型的变量占据不同的大小. Java中共有8种基本数据类型,包括4 种整型.2 种浮点型. ...

  10. 十分钟学会Markdown基本语法

    文章目录 Markdown 语法 一.标题 这是一级标题 这是二级标题 这是三级标题 这是四级标题 这是五级标题 这是六级标题 二.字体 三.引用 四.分割线 五.图片 六.超链接 七.列表 八.表格 ...