zoukankan      html  css  js  c++  java
  • CF961G Partitions(第二类斯特林数)

    题目

    CF961G

    前置

    斯特林数(Longrightarrow)斯特林数及反演总结

    做法

    相信大家能得出一个一眼式:$$Ans=sumlimits_{i=1}^n w_isumlimits_{s=1}^n scdot C_{n-1}^{s-1}egin{Bmatrix}k-1 -send{Bmatrix}$$

    然后就开始推式:

    [egin{aligned}\ Sum&=sumlimits_{s=1}^n scdot C_{n-1}^{s-1}egin{Bmatrix}n-s\k-1end{Bmatrix}\ &=sumlimits_{s=1}^n scdot C_{n-1}^{s-1}sumlimits_{i=0}^{k-1}frac{(-1)^i}{i!}frac{(k-i-1)^{n-2}}{(k-i-1)!}\ &=sumlimits_{i=0}^{k-1}frac{(-1)^i}{i!(k-i-1)!}sumlimits_{s=1}^n scdot C_{n-1}^{s-1}(k-i-1)^{n-s}\ &=sumlimits_{i=0}^{k-1}frac{(-1)^i}{i!(k-i-1)!}(sumlimits_{s=1}^nC_{n-1}^{s-1}(k-i-1)^{n-s}+sumlimits_{s=1}^n (s-1)C_{n-1}^{s-1}(k-i-1)^{n-s})\ &=sumlimits_{i=0}^{k-1}frac{(-1)^i}{i!(k-i-1)!}(sumlimits_{s=1}^nC_{n-1}^{s-1}(k-i-1)^{n-s}+(n-1)sumlimits_{s=1}^n C_{n-2}^{s-2}(k-i-1)^{n-s})\ &=sumlimits_{i=0}^{k-1}frac{(-1)^i}{i!(k-i-1)!}((k-i)^{n-1}+(n-1)(k-i)^{n-2})\ &=sumlimits_{i=0}^{k-1}frac{(-1)^i}{i!(k-i-1)!}(k-i)^{n-2}(k-i+n-1)\ end{aligned}]

    然而。。。这。。。比赛的时候能推出这么一大堆式子的**是神仙吧

    于是有种更简单的方法:(|S|sum w_i)
    我们可以理解为:划分好集合后,每个点都对当前点有(w_i)的贡献

    自己对自己的贡献显然就是(egin{Bmatrix}n\kend{Bmatrix})
    其他点对本身的贡献就是先分好(k)个集合,再放进去,((n-1)egin{Bmatrix}n-1\kend{Bmatrix})

    [Ans=sumlimits_{i=1}^nw_i(egin{Bmatrix}n\kend{Bmatrix}+(n-1)egin{Bmatrix}n-1\kend{Bmatrix}) ]

    Code

    有关斯特林数及反演的更多姿势(Longrightarrow)点这里

    #include<cstdio>
    typedef int LL;
    const LL mod=1e9+7,maxn=2e5+9;
    inline LL Read(){
        LL x(0),f(1); char c=getchar();
        while(c<'0' || c>'9'){
            if(c=='-') f=-1; c=getchar();
        }
        while(c>='0' && c<='9'){
            x=(x<<3)+(x<<1)+c-'0'; c=getchar();
        }
        return x*f;
    }
    inline LL Pow(LL base,LL b){
        LL ret(1);
        while(b){
            if(b&1) ret=1ll*ret*base%mod; base=1ll*base*base%mod; b>>=1;
        }return ret;
    }
    LL fav[maxn],fac[maxn];
    inline LL Get(LL n,LL m){
        LL ret(0);
        for(LL i=0;i<=m;++i)
            ret=1ll*(ret+1ll*(i&1?mod-1:1)*fav[i]%mod*Pow(m-i,n)%mod*fav[m-i]%mod)%mod;
        return ret;
    }
    LL n,sum,k;
    LL w[maxn];
    int main(){
        n=Read(); k=Read();
        for(LL i=1;i<=n;++i){
            w[i]=Read();
            (sum+=w[i])%=mod;
        }
        fac[0]=fac[1]=1;
        for(LL i=2;i<=n;++i) fac[i]=1ll*fac[i-1]*i%mod;
        fav[n]=Pow(fac[n],mod-2);
        for(LL i=n;i>=1;--i) fav[i-1]=1ll*fav[i]*i%mod;
        printf("%d
    ",1ll*sum*((1ll*Get(n,k)%mod+1ll*(n-1)*Get(n-1,k)%mod)%mod)%mod);
        return 0;
    }
    
  • 相关阅读:
    HTTP协议
    JavaScript学习(一)
    Cookie&Session
    注解初学
    反射初学
    XML
    Web概念
    Response对象
    Servlet
    LeetCode Notes_#617 Merge Two Binary Trees
  • 原文地址:https://www.cnblogs.com/y2823774827y/p/10708872.html
Copyright © 2011-2022 走看看