BZOJ 4555

一道模板题。

第二类斯特林数有公式:

$$S(n, m) = \frac{1}{m!}\sum_{i = 0}^{m}(-1)^i\binom{m}{i}(m - i)^n$$

考虑它的组合意义:$S(n, m)$表示$n$个不相同的小球放到$m$个相同的盒子里而且不能有空盒的方案数。

我们枚举空盒有$i$个,然后进行容斥。因为盒子没有区别,所以最后得到的值还要除以$m!$。

本题要求:

$$\sum_{i = 0}^{n}\sum_{j = 0}^{i}S(i, j)*2^j*(j!)$$

$$=\sum_{j = 0}^{n}2^j*(j!)\sum_{i = 0}^{n}S(i, j)$$

$$=\sum_{j = 0}^{n}2^j*(j!)\sum_{i = 0}^{n}\frac{1}{j!}\sum_{k = 0}^{j}(-1)^k\binom{j}{k}(j - k) ^ i$$

$$=\sum_{j = 0}^{n}2^j\sum_{i = 0}^{n}\sum_{k = 0}^{j}(-1)^k\frac{j!}{k!(j - k)!}*(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)^i}{(j - k)!}$$

记$f(i) = \frac{(-1^k)}{k!}$,$g(i) = \frac{\sum_{j = 0}^{n}i^j}{(i)!}$,

因为$S(0, 0) = (-1)^0 * 1 * 0^0 = 1$,所以记$g(0) = 1$,$g(1) = n + 1$,剩下代入等比数列求和公式。

那么原式化为

$$\sum_{i = 0}^{n}2^i*(i!)(f*g)(i)$$

做一遍$NTT$就好了。

时间复杂度$O(nlogn)$。

Code:

#include <cstdio>
#include <cstring>
using namespace std;
typedef long long ll; const int N = 3e5 + ;
const ll P = 998244353LL; int n, lim = , pos[N];
ll f[N], g[N], fac[N], inv[N], bin[N]; template <typename T>
inline void swap(T &x, T &y) {
T t = x; x = y; y = t;
} template <typename T>
inline void inc(T &x, T y) {
x += y;
if(x >= P) x -= P;
} inline ll fpow(ll x, ll y) {
ll res = 1LL;
for (; y > ; y >>= ) {
if (y & ) res = res * x % P;
x = x * x % P;
}
return res;
} inline void prework() {
int l = ;
for (; lim <= n * ; ++l, lim <<= );
for (int i = ; i < lim; i++)
pos[i] = (pos[i >> ] >> ) | ((i & ) << (l - ));
} inline void ntt(ll *c, int opt) {
for (int i = ; i < lim; i++)
if (i < pos[i]) swap(c[i], c[pos[i]]);
for (int i = ; i < lim; i <<= ) {
ll wn = fpow(, (P - ) / (i << ));
if(opt == -) wn = fpow(wn, P - );
for (int len = i << , j = ; j < lim; j += len) {
ll w = 1LL;
for (int k = ; k < i; k++, w = w * wn % P) {
ll x = c[j + k], y = w * c[j + k + i] % P;
c[j + k] = (x + y) % P, c[j + k + i] = (x - y + P) % P;
}
}
} if (opt == -) {
ll invP = fpow(lim, P - );
for (int i = ; i < lim; i++)
c[i] = c[i] * invP % P;
}
} int main() {
scanf("%d", &n); bin[] = fac[] = 1LL;
for (int i = ; i <= n; i++) {
fac[i] = fac[i - ] * i % P;
bin[i] = bin[i - ] * 2LL % P;
}
inv[n] = fpow(fac[n], P - );
for (int i = n - ; i >= ; i--) inv[i] = inv[i + ] * (i + ) % P; /* for (int i = 0; i <= n; i++)
printf("%lld%c", inv[i] * fac[i] % P, i == n ? '\n' : ' '); */ for (int i = ; i <= n; i++) {
f[i] = ((i & ) ? (-1LL) : (1LL)) * inv[i] % P;
if(f[i] < ) f[i] += P;
if(i == ) g[i] = 1LL;
else if (i == ) g[i] = n + ;
else g[i] = (fpow(i, n + ) - + P) % P * fpow(i - , P - ) % P;
g[i] = g[i] * inv[i] % P;
} prework();
ntt(f, ), ntt(g, );
for (int i = ; i < lim; i++) f[i] = f[i] * g[i] % P;
ntt(f, -); ll ans = 0LL;
for (int i = ; i <= n; i++)
inc(ans, bin[i] * fac[i] % P * f[i] % P); printf("%lld\n", ans);
return ;
}

最新文章

  1. (转) 从0开始搭建SQL Server AlwaysOn 第三篇(配置AlwaysOn)
  2. DeprecatedAttribute vs. ObsoleteAttribute
  3. 元素堆叠问题、z-index、position
  4. Python基础(深、浅拷贝)
  5. Service 与 Thread 的区别
  6. C++列出完数
  7. IT架构之IT架构标准——思维导图
  8. 瞎折腾之Mvc WebApi的使用以及跨域问题
  9. HDU5764 After a Sleepless Night 树形乱搞题
  10. Struts2零碎点整理
  11. WCF入门教程一[什么是WCF]--转载只为学习收藏
  12. VIM中的正则表达式及替换命令
  13. Java异常基础Exception
  14. java基础----&gt;Zip压缩的使用(转)
  15. Android底层音频声道耳机插头和开关壳体的发展
  16. 2017PHP程序员的进阶之路
  17. JS的深浅拷贝
  18. 字典树HihoCoder - 1014
  19. laravel中使用event
  20. 使用Nginx Upstream 部署 OpenERP

热门文章

  1. C#操作带名称空间的xml
  2. 选择第n大的数(分治法和排列实现)
  3. 《DSP using MATLAB》示例Example7.15
  4. debezium 数据变更工具使用
  5. excel oracle字段命名(大写下划线分词)转 驼峰命名
  6. datetimebox
  7. 记一次印象有点深刻的坑(bug)
  8. 使用resteasy作为dubbox消费者
  9. Win7旗舰版一直显示检查更新的问题
  10. 把OnDraw和OnPaint弄清楚(转贴)