• CF961G Partitions


    CF961G Partitions题解

    题意:

    给出(n) 个物品, 每个物品有一个权值(w_i)

    定义一个集合(S) 的权值(W(S)=|S|sumlimits_{xin S}w_x)

    定义一个划分的权值为(W'(R)=sumlimits_{Ssubseteq R}W(S))

    求将(n) 个物品划分成(k) 个集合的所有方案的权值和

    (n,kle2 imes10^5,w_ile10^9)

    题解:

    首先看出每个物品"地位"相同, 对答案的贡献肯定是(W_i*K)的形式, 所有的K都相等, 所以只需求出物品一的K就行

    一个比较显然((naive))的想法, 枚举物品一所在集合大小

    [K = sum_{i=1}^ni * large {left(^{n-1}_{i-1} ight)}*large{left{_{k-1}^{n-i} ight}} ]

    如果你是推式子带师, 可以一推, 但想我这样蒟蒻只能另辟蹊径

    在一种划分方案中, 物品一的贡献为它所在集合大小, 相当于它对本集和中的所有点都有贡献, 它自己对自己的贡献显然是划分的方案数(left{^n_k ight}), 对其他点的贡献相当于把剩下(n-1)个点划分, 再将其放入任意集合中, 即对所有集合中的点均有贡献, 所以答案为

    [large{Ans = (sum_{i=1}^nw_i)(left{^n_k ight}+(n+1)left{^{n-1}_{~~k} ight})} ]

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define ll long long
    using namespace std;
    const int P = 1e9+7;
    
    ll fpw(ll x, ll mi) {
    	ll res = 1;
    	while (mi) {
    		if (mi & 1) res = res * x % P;
    		x = x * x % P;
    		mi >>= 1;
    	}
    	return res;
    }
    
    template <typename T>
    void read(T &x) {
        x = 0; bool f = 0;
        char c = getchar();
        for (;!isdigit(c);c=getchar()) if (c=='-') f=1;
        for (;isdigit(c);c=getchar()) x=x*10+(c^48);
        if (f) x=-x;
    }
    
    template <typename T>
    void write(T x) {
        if (x < 0) putchar('-'), x = -x;
        if (x >= 10) write(x / 10);
        putchar('0' + x % 10);
    }
    
    const int N = 500050;
    ll jie[N], inv[N];
    void prework(void) {
    	const int Maxn = 300000;
    	jie[0] = jie[1] = inv[0] = inv[1] = 1;
    	for (int i = 2;i <= Maxn; i++) 
    		jie[i] = jie[i-1] * i % P, 
    		inv[i] = (P - P / i) * inv[P % i] % P;
    	for (int i = 2;i <= Maxn; i++) inv[i] = inv[i-1] * inv[i] % P;
    }
    
    
    ll strling(ll n, ll m) {
    	if (m > n) return 0;
    	ll ans = 0;
    	for (int i = 0;i <= m; i++) {
    		if ((m - i) & 1) ans -= fpw(i, n) * inv[i] % P * inv[m-i] % P;
    		else ans += fpw(i, n) * inv[i] % P * inv[m-i] % P;
    		ans %= P;
    	}
    	return (ans + P) % P;
    }
    
    ll sum;
    int main() {
    	prework();
    	int n, k; read(n), read(k);
    	for (int i = 1;i <= n; i++) {
    		ll x; read(x); sum += x;
    	}
    	sum %= P;
    	sum = sum * (strling(n, k) + (n - 1) * strling(n - 1, k) % P) % P;
    	cout << sum << endl;
    	return 0;
    }
    
  • 相关阅读:
    PRCT-1302 the OCR has an invalid ip address
    函数listen
    函数bind
    函数socket
    lamp。查看版本
    yii 日期插件
    UCenter 的目录结构
    API接口
    返回标签数据示例 (PHP)
    应用接口函数
  • 原文地址:https://www.cnblogs.com/Hs-black/p/12234144.html
Copyright © 2020-2023  润新知