• 【题解】Codeforces 961G Partitions


    【题解】Codeforces 961G Partitions

    cf961G

    好题啊哭了,但是如果没有不小心看了一下pdf后面一页的提示根本想不到

    题意

    已知(U={w_i}),求:

    [sum _{S}sum_{sin S}|s|sum_{w in s} w, S是U的一个k划分 ]

    转换1

    考虑这个(|s|)有点麻烦,稍微思考一下可以发现,我们最后的答案和(w_i)的分布没有关系,他们的贡献系数是一样的。答案只和他们的和有关。

    转换2

    考虑定位某个(w_i)对答案产生的贡献(w_i imes p),最后让(sum w)乘上(p)就是答案。

    然后就是喜闻乐见的套路时间了。这类与分配的集合的大小有关的计数题,可以用微扰法求出每一个元素的贡献。

    考虑(|s|)每增大一,(p)就大一。考虑自己对于自己的贡献,这部分贡献就是(egin{Bmatrix}n\kend{Bmatrix})

    然后考虑其他元素对自己的贡献,贡献就是钦定当前选定的一个其他元素和(w_i)在同一集合的划分方案数,此时可以用微扰法,先让其他(n-1)个元素自己先划分好,然后我在直接加入有(w_i)的那个集合,那么一个"其他元素"的贡献就是(egin{Bmatrix}n-1\kend{Bmatrix})。总共有(n-1)个其他元素。

    所以最后的答案是

    [sum w imes(egin{Bmatrix}n\kend{Bmatrix}+(n-1)egin{Bmatrix}n-1\kend{Bmatrix}) ]

    容斥球斯特林数即可。

    //@winlere
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    
    
    using namespace std;  typedef long long ll;
    inline int qr(){
          register int ret=0,f=0;
          register char c=getchar();
          while(c<48||c>57)f|=c==45,c=getchar();
          while(c>=48&&c<=57) ret=ret*10+c-48,c=getchar();
          return f?-ret:ret;
    }
    const int mod=1e9+7;
    const int maxn=2e5+5;
    int jc[maxn];
    int inv[maxn];
    int n,s,k,ans;
    inline int Pow(const int&base,const int&p){
          register int ret=1;
          for(register int t=p,b=base%mod;t;t>>=1,b=1ll*b*b%mod)
    	    if(t&1) ret=1ll*ret*b%mod;
          return ret;
    }
    
    inline int c(const int&n,const int&m){
          if(n<m)return 0;
          return 1ll*jc[n]*inv[m]%mod*inv[n-m]%mod;
    }
    
    
    inline int stirlin(const int&n,const int&m){
          register int ret=0;
          for(register int t=0,delta;t<m;++t){
    	    delta=1ll*c(m,t)*Pow(m-t,n)%mod;
    	    if(t&1)delta=mod-delta;
    	    ret=(ret+delta)%mod;
          }
          return 1ll*ret*inv[m]%mod;
    }
    
    int main(){
          
          jc[0]=inv[0]=1;
          for(register int t=1;t<maxn;++t)
    	    jc[t]=1ll*jc[t-1]*t%mod,inv[t]=Pow(jc[t],mod-2);
          n=qr();k=qr();
          for(register int t=1;t<=n;++t)
    	    s=(s+qr()%mod)%mod;
          if(s<0)s+=mod;
          ans=1ll*s*(stirlin(n,k)+1ll*(n-1)*stirlin(n-1,k)%mod)%mod;
          cout<<ans<<endl;
          return 0;
    }
    
    
  • 相关阅读:
    复习提纲
    查看版本和存储的地方
    0到255的颜色
    stixel-world和psmnet结合出现的问题
    python plt 保存jpg出错
    三和韓長庚 著 正易 對讀 161-200
    startActivity、 startActivityForResult 、广播的使用
    01背包+卡精度 Hdu 2955
    c++ string 之 find_first_not_of 源码
    java:[1,0] illegal character: 65279 问题
  • 原文地址:https://www.cnblogs.com/winlere/p/11047829.html
Copyright © 2020-2023  润新知