CF932E
https://codeforces.com/problemset/problem/932/E
求 \(\sum\limits_{i=1}^n {n\choose i} i^k\)。
\(n\le 1e9,k\le 5e3\)
\[\begin{align*}
f_{n,k} &= \sum\limits_{i=1}^n {n\choose i} i^k \\
&=\sum\limits_{i=1}^n\bigg[{n-1\choose i-1} + {n-1\choose i}\bigg]i^k \\
&=\sum\limits_{i=1}^n{n-1\choose i-1}i^k+\sum\limits_{i=1}^{n-1}{n-1\choose i}i^k \\
&=\sum\limits_{i=1}^n\frac{i}{n}{n\choose i}i^k+f_{n-1,k} \\
&=\frac{1}{n}\sum\limits_{i=1}^n{n\choose i}i^{k+1}+f_{n-1,k} \\
&=\frac{1}{n}f_{n,k+1}+f_{n-1,k} \\
移项得 f_{n,k} = n(f_{n,k-1} - f_{n-1,k-1})
\end{align*}
\]
第二维一直减,\(f_{n,0}=\sum\limits_{i=1}^n{n\choose i} =2^n-1\)。
\(n\lt k\) 时,\(f_{1,k}=1\)。
复杂度 \(O(k^2)\)。
#include <bits/stdc++.h>
using namespace std;
#define int long long
int read() {
int s = 0, w = 1;
char c = getchar();
while (!isdigit(c)) {
if (c == '-') w = -1;
c = getchar();
}
while (isdigit(c)) {
s = s * 10 + c - 48;
c = getchar();
}
return s * w;
}
void pr(int x) {
if (x < 0)
putchar('-'), x = -x;
if (x > 9)
pr(x / 10);
putchar(x % 10 + 48);
}
#define end_ putchar('\n')
#define spc_ putchar(' ')
const int maxN = 5e3 + 7;
const int mod = 1e9 + 7;
int ksm(int a, int b) {
int res = 1;
while (b) {
if (b & 1) res = res * a % mod;
a = a * a % mod;
b >>= 1;
}
return res;
}
int mp[maxN][maxN], P;
int f(int n, int k) {
if (mp[n - P][k] != -1) return mp[n - P][k];
if (k == 0) return (ksm(2, n) - 1 + mod) % mod;
if (n == 1) return 1;
int res = (f(n, k - 1) - f(n - 1, k - 1) + mod) % mod * n % mod;
mp[n - P][k] = res;
return res;
}
signed main() {
// freopen("1.in", "r", stdin);
// freopen("1.out", "w", stdout);
memset(mp, 255, sizeof(mp));
int n = read(), k = read();
P = n - k;
pr(f(n, k)), end_;
}