zoukankan      html  css  js  c++  java
  • 题解 CF961G 【Partitions】

    题目传送门

    题目大意

    给出(n,k),以及(w_{1,2,..,n}),定义一个集合(S)的权值(W(S)=|S|sum_{xin S} w_x),定义一个划分(R)的权值为(sum_{Sin R} W(S))。求出每种划分权值之和。

    思路

    这个题目有两种方法。一种就是直接从一眼式中暴推出答案,另外一种就是考虑组合意义,这里着重介绍后面一种。

    我们发现(W(S))实际上就等价于在(S)中的元素会对该集合中每个元素提供(w_i)的贡献。于是,我们考虑一个点会产生的贡献,首先对它自己会有(w_iegin{Bmatrix}n\kend{Bmatrix})的贡献,对其他点有((n-1)egin{Bmatrix}n-1\kend{Bmatrix}w_i)的贡献。这里解释一下后面那个,可以理解为先把(n-1)个分到(k)个盒子里(如果要产生贡献肯定要有跟它在同一个集合的元素),然后我可以加到这(k)里面任意一个,一共就是(n-1)个元素。

    于是,我们得到答案就是:

    [(egin{Bmatrix}n\kend{Bmatrix}+(n-1)egin{Bmatrix}n-1\kend{Bmatrix})(sum_{i=1}^{n} w_i) ]

    ( exttt{Code})

    #include <bits/stdc++.h>
    using namespace std;
    
    #define Int register int
    #define mod 1000000007
    #define MAXN 200005
    
    template <typename T> inline void read (T &t){t = 0;char c = getchar();int f = 1;while (c < '0' || c > '9'){if (c == '-') f = -f;c = getchar();}while (c >= '0' && c <= '9'){t = (t << 3) + (t << 1) + c - '0';c = getchar();} t *= f;}
    template <typename T,typename ... Args> inline void read (T &t,Args&... args){read (t);read (args...);}
    template <typename T> inline void write (T x){if (x < 0){x = -x;putchar ('-');}if (x > 9) write (x / 10);putchar (x % 10 + '0');}
    
    int n,k,w[MAXN],fac[MAXN],ifac[MAXN];
    int mul (int a,int b){return 1ll * a * b % mod;}
    int dec (int a,int b){return a >= b ? a - b : a + mod - b;}
    int add (int a,int b){return a + b >= mod ? a + b - mod : a + b;}
    int binom (int a,int b){return a >= b ? mul (fac[a],mul (ifac[b],ifac[a - b])) : 0;}
    int qkpow (int a,int b){int res = 1;for (;b;b >>= 1,a = mul(a,a)) if (b & 1) res = mul (res,a) % mod;return res;}
    int Sitelin (int n,int m){int res = 0;for (Int i = 0,tmp;i <= m;++ i) tmp = mul (binom (m,i),qkpow (i,n)),m - i & 1 ? (res = dec (res,tmp)) : (res = add (res,tmp));return 1ll * res * ifac[m] % mod;}
    
    signed main(){
    	read (n,k);fac[0] = 1;int sum = 0;
    	for (Int i = 1;i <= n;++ i) read (w[i]),sum = add (sum,w[i]);
    	for (Int i = 1;i <= k;++ i) fac[i] = mul (fac[i - 1],i);ifac[k] = qkpow (fac[k],mod - 2);for (Int i = k;i;-- i) ifac[i - 1] = mul (ifac[i],i);
    	write (mul (sum,add (Sitelin (n,k),mul (n - 1,Sitelin (n - 1,k))))),putchar ('
    ');
    	return 0;
    }
    
  • 相关阅读:
    POJ-2018 Best Cow Fences(二分加DP)
    POJ-2039 To and Fro
    POJ-2029 Get Many Persimmon Trees(动态规划)
    POJ-2081 Recaman's Sequence
    POJ-2081 Terrible Sets(暴力,单调栈)
    Java实现 LeetCode 740 删除与获得点数(递推 || 动态规划?打家劫舍Ⅳ)
    Java实现 LeetCode 739 每日温度(暴力循环)
    Java实现 LeetCode 739 每日温度(暴力循环)
    Java实现 LeetCode 739 每日温度(暴力循环)
    Java实现 LeetCode 738 单调递增的数字(暴力)
  • 原文地址:https://www.cnblogs.com/Dark-Romance/p/13419891.html
Copyright © 2011-2022 走看看