[CF961G] Partitions

神仙题(对我这种蒟蒻来说)
题解可以去\(h\)\(\color{red}{eyujun}\)的博客看
这里
关于如何计算任意一个第二类斯特林数
我们有
\[ \begin{Bmatrix}n\\m\end{Bmatrix}=\frac{1}{m!}\sum\limits_{k=0}^m(-1)^kC(m,k)(m-k)^n\]
这样我们可以在\(O(m\log n)\)内算出任意一个第二类斯特林数了

#include<bits/stdc++.h>
using namespace std;
#define maxn 200005
#define ll long long
#define p 1000000007
inline void read(int& x)
{
    x=0;char c=getchar();
    while(!isdigit(c)) c=getchar();
    while(isdigit(c)) x=x*10+c-'0',c=getchar();
}
int fac[maxn],inv[maxn];

inline int qpow(int x,int y)
{
    int ans=1;
    while(y)
    {
        if(y&1) ans=1ll*ans*x%p;
        x=1ll*x*x%p;
        y>>=1;
    }
    return ans;
}
inline int C(int n,int m)
{
    return 1ll*fac[n]*inv[m]%p*inv[n-m]%p;
}
inline int S(int n,int m)
{
    int ans=0;
    for(int i=0;i<=m;++i)
    {
        if(i&1) ans=(0ll+ans+p-1ll*C(m,i)*qpow(m-i,n))%p;
        else ans=(0ll+ans+1ll*C(m,i)*qpow(m-i,n))%p;
    }
    ans=(ans%p+p)%p;
    ans=1ll*ans*inv[m]%p;
    return ans;
}
int main()
{
    int n,k,w;
    ll sum=0;
    read(n);read(k);
    for(int i=1;i<=n;++i) read(w),sum=(sum+w)%p;
    fac[0]=inv[0]=1;
    for(int i=1;i<=n;++i) fac[i]=1ll*fac[i-1]*i%p;
    inv[n]=qpow(fac[n],p-2);
    for(int i=n-1;i;--i) inv[i]=1ll*inv[i+1]*(i+1)%p;
    sum=1ll*sum*((0ll+S(n,k)+1ll*(n-1)*S(n-1,k))%p)%p;
    printf("%lld\n",sum);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/123789456ye/p/12204235.html
今日推荐