[HEOI2016/TJOI2016]求和
嘟嘟嘟
好多人(神仙)都说这是NTT例题,然后我就做了……
做这题,需要一下前置技能:
1.第二类斯特林数
2.NTT
3.没有公式恐惧症
额……不会斯特林数的话(就像我),知道通项公式也行。
这个博客挺好:第二类斯特林数总结
然后就是一顿暴推了。
首先如果直接往原式里带通项公式的话好像搞不出来,这时候需要用点技巧,换一下枚举顺序:
\]
讲道理\(i\)应该从\(j\)枚举到\(n\),但因为\(S(i, j) = 0(i < j)\),所以就改成了从\(0\)枚举。
然后代入第二类斯特林数通项公式\(S(n, m) = \frac{1}{m!} \sum _ {k = 0} ^ {m} (-1) ^ k C(m, k) (m - k) ^ n\):
f(n)
&= \sum_{j = 0} ^ {n} 2 ^ j * (j!) \sum_{i = 0} ^ {n} \sum_{k = 0} ^ {j} (-1) ^ k C(j, k) * (j - k) ^ i \\
&= \sum_{j = 0} ^ {n} 2 ^ j * (j!) \sum_{k = 0} ^ {j} (-1) ^ k C(j, k) * \sum_{i = 0} ^ {n} (j - k) ^ i \\
&= \sum_{j = 0} ^ {n} 2 ^ j * (j!) \sum_{k = 0} ^ {j} \frac{(-1) ^ k}{k!} * \frac{\sum_{i = 0} ^ {n} (j - k) ^ n}{(j - k)!}
\end{align*}\]
发现\(\sum _ {i = 0} ^ {n} (j - k) ^ n\)是一个等比数列,\(O(1)\)可解。
然后令\(A(t) = \frac{(-1) ^ t}{t!}\),\(B(t) = \frac{\sum _ {i = 0} ^ {n} t ^ n}{t!}\)。这俩都可以\(O(n)\)预处理出来。
于是上式变成了
\]
后面的\(\sum\)是一个卷积的形式,NTT就行,于是这题就完事了。
(反正自己没推出来)
#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<vector>
#include<stack>
#include<queue>
using namespace std;
#define enter puts("")
#define space putchar(' ')
#define Mem(a, x) memset(a, x, sizeof(a))
#define In inline
typedef long long ll;
typedef double db;
const int INF = 0x3f3f3f3f;
const db eps = 1e-8;
const ll mod = 998244353;
const ll G = 3;
const int maxn = 1e5 + 5;
const int maxl = 4e6 + 5;
inline ll read()
{
ll ans = 0;
char ch = getchar(), last = ' ';
while(!isdigit(ch)) last = ch, ch = getchar();
while(isdigit(ch)) ans = (ans << 1) + (ans << 3) + ch - '0', ch = getchar();
if(last == '-') ans = -ans;
return ans;
}
inline void write(ll x)
{
if(x < 0) x = -x, putchar('-');
if(x >= 10) write(x / 10);
putchar(x % 10 + '0');
}
int n, rev[maxl];
ll fac[maxn], inv_f[maxn], inv[maxn];
ll A[maxl], B[maxl];
In ll quickpow(ll a, ll b)
{
ll ret = 1;
for(; b; b >>= 1, a = a * a % mod)
if(b & 1) ret = ret * a % mod;
return ret;
}
In void init()
{
fac[0] = fac[1] = 1;
for(int i = 2; i <= n; ++i) fac[i] = fac[i - 1] * i % mod;
inv_f[n] = quickpow(fac[n], mod - 2);
for(int i = n - 1; i >= 0; --i) inv_f[i] = inv_f[i + 1] * (i + 1) % mod;
inv[0] = inv[1] = 1;
for(int i = 2; i <= n; ++i) inv[i] = inv[mod % i] * (mod - mod / i) % mod;
for(int i = 0, flg = 1; i <= n; ++i, flg *= (-1)) A[i] = (inv_f[i] * flg + mod) % mod;
B[0] = 1; B[1] = n + 1;
for(int i = 2; i <= n; ++i) B[i] = (quickpow(i, n + 1) - 1 + mod) % mod * inv[i - 1] % mod * inv_f[i] % mod;
}
In void ntt(ll* a, int len, bool flg)
{
for(int i = 0; i < len; ++i) if(i < rev[i]) swap(a[i], a[rev[i]]);
for(int i = 1; i < len; i <<= 1)
{
ll ng = quickpow(G, (mod - 1) / (i << 1));
for(int j = 0; j < len; j += (i << 1))
{
ll g = 1;
for(int k = 0; k < i; ++k, g = g * ng % mod)
{
ll tp1 = a[k + j], tp2 = a[k + j + i] * g % mod;
a[k + j] = (tp1 + tp2) % mod, a[k + j + i] = (tp1 - tp2 + mod) % mod;
}
}
}
if(flg) return;
ll inv = quickpow(len, mod - 2); reverse(a + 1, a + len);
for(int i = 0; i < len; ++i) a[i] = a[i] * inv % mod;
}
int main()
{
n = read();
init();
int len = 1, lim = 0;
while(len <= n + n) len <<= 1, ++lim;
for(int i = 0; i < len; ++i) rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << (lim - 1));
ntt(A, len, 1); ntt(B, len, 1);
for(int i = 0; i < len; ++i) A[i] = A[i] * B[i] % mod;
ntt(A, len, 0);
ll ans = 0, tp = 1;
for(int i = 0; i <= n; ++i, tp = (tp + tp) % mod) ans = (ans + fac[i] * tp % mod * A[i] % mod) % mod;
write(ans), enter;
return 0;
}
[HEOI2016/TJOI2016]求和的更多相关文章
- 洛谷 P4091 [HEOI2016/TJOI2016]求和 解题报告
P4091 [HEOI2016/TJOI2016]求和 题目描述 在2016年,佳媛姐姐刚刚学习了第二类斯特林数,非常开心. 现在他想计算这样一个函数的值: \[ f(n)=\sum_{i=0}^n\ ...
- 【LG4091】[HEOI2016/TJOI2016]求和
[LG4091][HEOI2016/TJOI2016]求和 题面 要你求: \[ \sum_{i=0}^n\sum_{j=0}^iS(i,j)*2^j*j! \] 其中\(S\)表示第二类斯特林数,\ ...
- [HEOI2016/TJOI2016]求和(第二类斯特林数)
题目 [HEOI2016/TJOI2016]求和 关于斯特林数与反演的更多姿势\(\Longrightarrow\)点这里 做法 \[\begin{aligned}\\ Ans&=\sum\l ...
- 【题解】P4091 [HEOI2016/TJOI2016]求和
[题解]P4091 [HEOI2016/TJOI2016]求和 [P4091 HEOI2016/TJOI2016]求和 可以知道\(i,j\)从\(0\)开始是可以的,因为这个时候等于\(0\).这种 ...
- LG4091 【[HEOI2016/TJOI2016]求和】
前置:第二类斯特林数 表示把\(n\)个小球放入\(m\)个不可区分的盒子的方案数 使用容斥原理分析,假设盒子可区分枚举至少有几个盒子为空,得到通项: \[S(n,m)=\frac{1}{m!}\su ...
- Luogu 4091 [HEOI2016/TJOI2016]求和
BZOJ 4555 一道模板题. 第二类斯特林数有公式: $$S(n, m) = \frac{1}{m!}\sum_{i = 0}^{m}(-1)^i\binom{m}{i}(m - i)^n$$ 考 ...
- 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! ...
- 【题解】Luogu P4091 [HEOI2016/TJOI2016]求和
原题传送门 \[\begin{aligned} a n s &=\sum_{i=0}^{n} \sum_{j=0}^{i}\left\{\begin{array}{c}{i} \\ {j}\e ...
- BZOJ 4555 Luogu P4091 [HEOI2016/TJOI2016]求和 (第二类斯特林数)
题目链接 (luogu) https://www.luogu.org/problem/P4091 (bzoj) https://www.lydsy.com/JudgeOnline/problem.ph ...
- [题解] LuoguP4091 [HEOI2016/TJOI2016]求和
传送门 首先我们来看一下怎么求\(S(m,n)\). 注意到第二类斯特林数的组合意义就是将\(m\)个不同的物品放到\(n\)个没有区别的盒子里,不允许有空盒子的方案数. 那么将\(m\)个不同的物品 ...
随机推荐
- Netty 系列七(那些开箱即用的 ChannelHandler).
一.前言 Netty 为许多通用协议提供了编解码器和处理器,几乎可以开箱即用, 这减少了你在那些相当繁琐的事务上本来会花费的时间与精力.另外,这篇文章中,就不涉及 Netty 对 WebSocket协 ...
- TCP连接与释放
TCP连接的建立 三次握手 TCP服务器进程先创建传输控制块TCB,时刻准备接受客户进程的连接请求,此时服务器就进入了LISTEN(监听)状态. TCP客户进程也是先创建传输控制块TCB,然后向服务器 ...
- 今天学习了flex布局
前言:这个网站详细讲了水平.垂直.水平垂直的css方法.https://css-tricks.com/centering-css-complete-guide/ 布局的传统解决方案,基于盒状模型,依赖 ...
- mapper代理开发步骤
1:先写Mapper接口,UserMapper.java 2:然后遵循4条开发规范,写映射文件,UserMapper.xml 3:将映射文件,UserMapper.xml加入到SqlMapConfig ...
- js 依据“;”折行
function roomIds(roomid) { // var str = roomid.replace(/;/g,'\r\n'); if (roomid) { var str = roomid. ...
- ICML 2018 | 从强化学习到生成模型:40篇值得一读的论文
https://blog.csdn.net/y80gDg1/article/details/81463731 感谢阅读腾讯AI Lab微信号第34篇文章.当地时间 7 月 10-15 日,第 35 届 ...
- Simplest Python K-Way Merging Sort|最简单的Python k路归并排序
想做这个好长时间了,因为有一篇Dreamworks的论文<Coherent Out-of-Core Point-Based Global Illumination>提到了这个,一直没时间做 ...
- 使用git将Android源码上传到github
下面举Android的Browser源码通过git保存到github上 首先在github.com官网new repository一个仓库 在Repository name哪里填入Browser然后创 ...
- seajs的原理以及基本使用
seajs模块化开发 模块化开发,把整个文件分割成一个一个小文件. 使用方法 使用方法特别简单,首先在官网中下载sea.js,然后在页面中引入. index.html // 1.路径 // 2.回调 ...
- (python)数据结构---字符串
一.概述 由一个个字符组成的有序序列. 使用单引号.双引号.三引号引住的字符序列. 不可变.线性的数据结构. 二.字符串的相关操作 1.元素访问----下标 字符串是线性的数据结构,可以使用索引去访问 ...