zoukankan      html  css  js  c++  java
  • Codeforces 961G. Partitions

    Solution

    给定一个长度为 (n) 的序列 (a_i),你需要把这个序列分成非空的 (m) 组(可以在原数组的基础上打乱),一个组的权值是所有 组内的 (|S|*sum_{i=1}^{|S|}a_i),求所有分法中的所有组的权值和
    题面

    Solution

    考虑每一个点的贡献,每一个点的贡献是一样的,只需要考虑贡献次数就行了
    假设正在考虑 (x) 被计算的次数,那么如果有一个 (y) 和它在同一个集合中,就会有 (1) 的贡献(集合长度加 (1))
    那么我们把 (x) 单独拿出,只对剩下 (n-1) 进行分组,再把 (x) 拼进 (y) 所在的组,就可以产生贡献 (1) 的了
    所以总答案就是 ((S(n,m)+(n-1)*S(n-1,m))*sum_{i=1}^{n} a_i)
    第二类斯特林数用展开式算一下就好了

    #include<bits/stdc++.h>
    using namespace std;
    const int N=2e5+10,mod=1e9+7;
    inline int qm(int x,int k){
    	int sum=1;
    	while(k){
    		if(k&1)sum=1ll*sum*x%mod;
    		x=1ll*x*x%mod;k>>=1;
    	}
    	return sum;
    }
    int inv[N];
    inline int S(int n,int m){
    	int ret=0,t;
    	for(int i=0;i<=m;i++){
    		t=1ll*inv[i]*inv[m-i]%mod*qm(m-i,n)%mod;
    		if(i&1)ret=(ret-t+mod)%mod;
    		else ret=(ret+t)%mod;
    	}
    	return ret;
    }
    int main(){
      freopen("pp.in","r",stdin);
      freopen("pp.out","w",stdout);
      int n,m,ans=0,x;
      cin>>n>>m;
      inv[0]=1;for(int i=1;i<=m;i++)inv[i]=1ll*inv[i-1]*qm(i,mod-2)%mod;
      for(int i=1;i<=n;i++)scanf("%d",&x),ans=(ans+x)%mod;
      cout<<1ll*ans*(S(n,m)+1ll*S(n-1,m)*(n-1)%mod)%mod<<endl;
      return 0;
    }
    
    
  • 相关阅读:
    POJ 3280 Cheapest Palindrome
    POJ 1191 棋盘分割
    POJ 1260 Pearls
    HDOJ 4731 Minimum palindrome
    2013 ACM/ICPC Asia Regional Chengdu Online 1004 Minimum palindrome
    POJ 1836 Alignment
    POJ 3267 The Cow Lexicon
    POJ 1276 Cash Machine
    POJ 1837 Balance
    HDU 4554 叛逆的小明
  • 原文地址:https://www.cnblogs.com/Yuzao/p/8721673.html
Copyright © 2011-2022 走看看