[CF961G] Partitions
[题目链接]
https://codeforces.com/contest/961/problem/G
[题解]
首先每个物品是独立的 , 考虑其贡献 , 为 :
\(i\begin{Bmatrix}k - 1\\n - i\end{Bmatrix}{n - 1 \choose i - 1}\)
考虑暴力拆解斯特林数 , 化简得贡献
\(\sum{\frac{(-1)^{j}}{(j!)(k - j - 1)!}} \cdot ((k - j) ^ {n - 1} + (n - 1)(k - j) ^ {n - 2})\)
时间复杂度 : \(O(NlogN)\) (瓶颈在快速幂)
[代码]
#include<bits/stdc++.h>
using namespace std;
#define rep(i , l , r) for (int i = (l); i < (r); ++i)
typedef long long LL;
const int MN = 3e5 + 5 , mod = 1e9 + 7;
int N , K , sum , ans , fac[MN] , ifac[MN];
inline void inc(int &x , int y) {
x = x + y < mod ? x + y : x + y - mod;
}
inline void dec(int &x , int y) {
x = x - y >= 0 ? x - y : x - y + mod;
}
inline int qPow(int a , int b) {
if (b < 0) return 1;
int c = 1;
for (; b; b >>= 1 , a = 1ll * a * a % mod) if (b & 1) c = 1ll * c * a % mod;
return c;
}
int main() {
scanf("%d%d" , &N , &K);
for (int i = 1; i <= N; ++i) {
int x; scanf("%d" , &x);
inc(sum , x);
}
fac[0] = 1;
for (int i = 1; i <= N; ++i) fac[i] = 1ll * fac[i - 1] * i % mod;
ifac[N] = qPow(fac[N] , mod - 2);
for (int i = N - 1; i >= 0; --i) ifac[i] = 1ll * ifac[i + 1] * (i + 1) % mod;
for (int j = 0; j < K; ++j) {
int val = 1ll * ((j & 1) ? mod - 1 : 1) * ifac[j] % mod * ifac[K - 1 - j] % mod;
inc(ans , 1ll * val * qPow(K - j , N - 2) % mod * (K - j + N - 1) % mod);
}
printf("%d\n" , 1ll * sum * ans % mod);
return 0;
}