码迷,mamicode.com
首页 > 其他好文 > 详细

[Codeforces 961G]Partitions

时间:2018-04-05 20:00:25      阅读:157      评论:0      收藏:0      [点我收藏+]

标签:个数   元素   for   mes   mit   计算   UI   div   com   

Description

题库链接

给你 \(n\) 个不同的元素组成的集合 \(R\) ,每个元素有一个权值 \(w\) 。对于一个子集集合 \(S\) ,它的价值为 \(W(S)=|S|\cdot\sum\limits_{i\in S}w_i\) 。现要求将该集合 \(R\) 划分成 \(k\) 个互不相交的非空子集 \(S_i\) 。定义一种划分的价值为 \(\sum\limits_{i=1}^k W(S_i)\) 。求所有划分的价值和。对大质数取模。

\(1\leq k\leq n\leq 2\cdot 10^5\)

Solution

容易发现对于不同的元素,他对答案的贡献本质是相同的。即我们只要求出某一种元素在所有方案中出现的次数 \(sum\) ,那么答案就是 \(sum\times \sum\limits_{i=1}^n w_i\)

考虑如何求 \(sum\)

容易发现它对 \(sum\) 的贡献只与和它被划分到同一集合的元素的个数有关。

  1. 如果该元素被单独划分成一组,那么答案的贡献为 \(S(n-1, k-1)\) 。(其中形同 \(S(n, m)\) 的表示第二类斯特林数。)因为它单独分为一组,所以答案贡献为 \(1\) ,只要讨论其他 \(n-1\) 个元素怎么分即可;
  2. 如果不是单独分为一组,我们考虑用类似的方法来讨论。还是将其他的 \(n-1\) 个元素先分好,共 \(S(n-1,k)\) 种。接下来考虑剩下的元素该如何放。对于一种划分 \(n-1\) 个元素的情况。我们记每一个子集元素个数为 \(a_i\) 。那么答案应该是 \(\sum\limits_{i=1}^k a_i+1\) 。不过因为 \(\sum\limits_{i=1}^k a_i=n-1\) ,所以在这种划分情况下,该元素的贡献就是 \(n+k-1\) 。故总贡献为 \((n+k-1)\cdot S(n-1, k)\)

综上答案就是 \((S(n-1,k-1)+(n+k-1)\cdot S(n-1, k))\cdot\sum\limits_{i=1}^n w_i\)

\(S(n,m)\) 用通项公式计算就好了。

Code

#include <bits/stdc++.h>
using namespace std;
const int N = 2e5, yzh = 1e9+7;

int x, n, k, inv[N+5];

int quick_pow(int a, int b) {
    int ans = 1;
    while (b) {
        if (b&1) ans = 1ll*ans*a%yzh;
        a = 1ll*a*a%yzh, b >>= 1; 
    }
    return ans;
}
int S(int n, int m) {
    int ans = 0;
    for (int i = 0; i <= m; i++) {
        int t = 1ll*inv[i]*inv[m-i]%yzh*quick_pow(m-i, n)%yzh;
        if (i&1) (ans -= t) %= yzh;
        else (ans += t) %= yzh;
    }
    return ans;
}
void work() {
    scanf("%d%d", &n, &k); inv[0] = inv[1] = 1;
    for (int i = 2; i <= k; i++) inv[i] = -1ll*yzh/i*inv[yzh%i]%yzh;
    for (int i = 1; i <= k; i++) inv[i] = 1ll*inv[i-1]*inv[i]%yzh;
    int sum = 0;
    for (int i = 1; i <= n; i++) scanf("%d", &x), (sum += x) %= yzh;
    int ans = (S(n-1, k-1)+1ll*(n+k-1)*S(n-1, k)%yzh)%yzh;
    ans = 1ll*ans*sum%yzh;
    printf("%d\n", (ans+yzh)%yzh);
}
int main() {work(); return 0; }

[Codeforces 961G]Partitions

标签:个数   元素   for   mes   mit   计算   UI   div   com   

原文地址:https://www.cnblogs.com/NaVi-Awson/p/8723741.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!