传送门

题意:

\[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. 洛谷 Atcoder 题解 AT2585 【Colorful Leaderboard】

    目测 普及/提高- 难度. 思路 将 9 种可能的等级存储在数组里,则 min 值为分数为 0 ~ 3199 的颜色种类个数,max 值为 min 值加上分数 >3200 的人数. 特判 若分数 ...

  2. 【Taro】363- 玩转 Taro 跨端之 flex 布局篇

    Taro 是一套遵循 React 语法规范的跨平台开发解决方案,但是目前当我们使用 Taro 的时候,在不同平台上的开发体验还有不一致的地方,所以我们也都期待有一套跨平台统一的解决方案,能够以最小差异 ...

  3. Dubbo源码分析之SPI(二)

    一.概述 本篇文章是dubbo SPI源码分析的第二篇,接着第一篇继续分析dubbo SPI的内容,我们主要介绍 getDefaultExtension() 获取默认扩展点方法. 由于此方法比较简单, ...

  4. 用span写一个特殊样式的1

    用span写一个如下样式的 1 span { display: inline-block; width: 17px; height: 17px; background: var(--themeColo ...

  5. poj 2823 Sliding Windows (单调队列+输入输出挂)

    Sliding Window Time Limit: 12000MS   Memory Limit: 65536K Total Submissions: 73426   Accepted: 20849 ...

  6. 《Java基础知识》Java访问修饰符(访问控制符)

    Java 通过修饰符来控制类.属性和方法的访问权限和其他功能,通常放在语句的最前端.例如: public class className { // body of class } private bo ...

  7. JVM系列四(内存分配策略).

    一.概要 前面的文章介绍了对象的创建过程,其中第三步 -- 分配内存,只是简单的介绍了分配的方式 -- 指针碰撞.空闲列表,其实内存在堆上分配还大有文章嘞. 对象的内存分配,往大方向上讲,就是在堆上分 ...

  8. [ASP.NET Core 3框架揭秘] 配置[6]:多样化的配置源[上篇]

    .NET Core采用的这个全新的配置模型的一个主要的特点就是对多种不同配置源的支持.我们可以将内存变量.命令行参数.环境变量和物理文件作为原始配置数据的来源.如果采用物理文件作为配置源,我们可以选择 ...

  9. ajax添加请求头(添加Authorization字段)

    我们在发AJAX请求的时候可能会需要自定义请求头,在jQuery的$.ajax()方法中提供了beforeSend属性方便我们进行此操作. beforeSend: function(request) ...

  10. C#线程学习笔记九:async & await入门二

    一.异步方法返回类型 只能返回3种类型(void.Task和Task<T>). 1.1.void返回类型:调用方法执行异步方法,但又不需要做进一步的交互. class Program { ...