欢迎来到下蛋爷之家|

下蛋爷

园龄:4年2个月粉丝:8关注:23

CF932E Team Work 题解

Description

给定 n,k,求:

i=1n(ni)×ik

1k5000,1n109

Solution

看到那个 ik 很不爽,但是 k 很小,考虑用斯特林数改写一下:

ik=j=0k(ij){kj}j!

代回原式得:

i=0n(ni)j=0k(ij){kj}j!=j=0kj!{kj}i=0n(ni)(ij)=j=0kj!{kj}i=jnn!i!(ni)!i!j!(ij)!=n!j=0k{kj}i=jn(njij)(nj)!=n!j=0k1(nj)!{kj}i=0nj(nji)=n!j=0k2nj(nj)!{kj}

于是直接预处理出斯特林数即可做到 O(k2+klogn),如果用卷积预处理的话就可以做到 O(klogk+klogn)

Code

#include <bits/stdc++.h>
// #define int int64_t
using i64 = int64_t;
const int kMod = 1e9 + 7;
int s[5005][5005];
int qpow(int bs, int idx = kMod - 2) {
int ret = 1;
for (; idx; idx >>= 1, bs = (i64)bs * bs % kMod)
if (idx & 1)
ret = (i64)ret * bs % kMod;
return ret;
}
void dickdreamer() {
int n, k, ans = 0;
std::cin >> n >> k;
s[0][0] = 1;
for (int i = 1; i <= k; ++i) {
for (int j = 1; j <= i; ++j) {
s[i][j] = (s[i - 1][j - 1] + (i64)j * s[i - 1][j] % kMod) % kMod;
}
}
for (int i = 0, c = 1; i <= std::min(n, k); ++i) {
ans = (ans + (i64)s[k][i] * c % kMod * qpow(2, n - i) % kMod) % kMod;
c = (i64)c * (n - i) % kMod;
}
std::cout << ans << '\n';
}
int32_t main() {
#ifdef ORZXKR
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
#endif
std::ios::sync_with_stdio(0), std::cin.tie(0), std::cout.tie(0);
int T = 1;
// std::cin >> T;
while (T--) dickdreamer();
// std::cerr << 1.0 * clock() / CLOCKS_PER_SEC << "s\n";
return 0;
}
posted @   下蛋爷  阅读(10)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起