[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;
}
posted @ 2021-01-24 17:46  evenbao  阅读(75)  评论(0编辑  收藏  举报