123789456ye

已AFO

[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;
}
posted @ 2020-01-19 11:16  123789456ye  阅读(107)  评论(0编辑  收藏  举报