CF932E

斯特林反演

[sum_{i = 1} ^ n inom n i i^k ]

[= sum_{i = 0}^n inom n i sum_{j = 0}^k egin{Bmatrix} k \ j end{Bmatrix} i^{underline{j}} ]

[= sum_{i = 0}^n frac 1 {j!} sum_{j = 0}^k egin{Bmatrix} k \ j end{Bmatrix} inom n i inom i j ]

[= sum_{j = 0}^k frac 1 {j!} egin{Bmatrix} k \ j end{Bmatrix} sum_{i = j}^n inom n i inom i j ]

[= sum_{j = 0}^k frac 1 {j!} egin{Bmatrix} k \ j end{Bmatrix} sum_{i = j}^n inom n j inom {n - j} {i - j} ]

[= sum_{j = 0}^k frac 1 {j!} inom n j egin{Bmatrix} k \ j end{Bmatrix} sum_{i = 0}^{n - j} inom {n - j} {i} ]

[= sum_{j = 0}^k frac 1 {j!} inom n j egin{Bmatrix} k \ j end{Bmatrix} 2 ^ {n - j} ]

然后我们就得到了一个 (O(n logn)) 的解法

由于题目数据,我打的是 (O(n^2)) 的代码

#include <bits/stdc++.h>
using namespace std;
#define gc getchar
#define rg register
#define I inline
#define rep(i, a, b) for(int i = a; i <= b; ++i)
#define per(i, a, b) for(int i = a; i >= b; --i)
I int read(){
	rg char ch = gc();
	rg int x = 0, f = 0;
	while(!isdigit(ch)) f |= (ch == '-'), ch = gc();
	while(isdigit(ch)) x = (x << 1) + (x << 3) + (ch ^ 48), ch = gc();
	return f ? -x : x;
}
const int mod = 1e9 + 7, N = 5005;
int sa, a[N], k, c[N], fac[N], nxj[N];
int n, s2[N][N];
I int ksm(int a, int b){
	int ans = 1;
	while(b){ if(b & 1) ans = 1ll * ans * a % mod; b >>= 1; a = 1ll * a * a % mod; }
	return ans;
}
signed main(){
	n = read(), k = read();
	s2[0][0] = 1; nxj[0] = fac[0] = 1;
	rep(i, 1, k) fac[i] = 1ll * fac[i - 1] * i % mod, nxj[i] = 1ll * nxj[i - 1] * (n - i + 1) % mod;
	rep(i, 0, k) rep(j, 0, i) if(i && j) s2[i][j] = (s2[i - 1][j - 1] + 1ll * j * s2[i - 1][j]) % mod;
	int res = 0;
	rep(i, 0, min(n, k)) res = (res + 1ll * s2[k][i] * fac[i] % mod * nxj[i] % mod * ksm(fac[i], mod - 2) % mod * ksm(2, n - i) % mod) % mod;
	cout << res << endl;
	return 0;
}
原文地址:https://www.cnblogs.com/XiaoVsun/p/13056028.html