CF961G题解

很显然每个数的地位是相同的,所以考虑每个元素的贡献,最后乘上权值之和。

每个元素的贡献相当于将 \(n\) 个数划分成 \(k\) 个集合后,从与 \(1\) 号在同一个集合中的元素中选一个。(下面称这个集合为“第一集合”)

于是我们直接先把这个数选出来,然后考虑两种情况:第一集合的大小是否为 \(1\)

若大小为 \(1\),贡献显然是 \(\begin{Bmatrix}n-1\\k-1\end{Bmatrix}\),若大小不为 \(1\),则贡献是 \((n-1)\begin{Bmatrix}n-1\\k\end{Bmatrix}+k\begin{Bmatrix}n-1\\k\end{Bmatrix}\)

三个斯特林数的组合意义分别是:将剩下的元素划分进集合,选择除自身外的 \(n-1\) 个元素然后自身与其绑定,选择自身然后在 \(k\) 个集合中选择一个集合当做“第一集合”。

可以根据第二类斯特林数的递推公式得知这个是 \(\begin{Bmatrix}n\\k\end{Bmatrix}+(n-1)\begin{Bmatrix}n-1\\k\end{Bmatrix}\)

#include<cstdio>
typedef unsigned ui;
const ui M=2e5+5,mod=1e9+7;
ui n,k,pw1[M],pw2[M],inv[M],ifac[M];ui top,pri[M],pos[M];
inline ui pow(ui a,ui b){
	ui ans(1);
	for(;b;b>>=1,a=1ull*a*a%mod)if(b&1)ans=1ull*ans*a%mod;
	return ans;
}
inline void sieve(){
	ui i,j,x;pw1[1]=inv[1]=pw2[0]=ifac[0]=ifac[1]=1;pw2[1]=k;
	for(i=2;i<=k;++i){
		if(!pos[i])pri[pos[i]=++top]=i,pw1[i]=pow(i,n);
		for(j=1;j<=pos[i]&&(x=i*pri[j])<=k;++j)pos[x]=j,pw1[x]=1ull*pw1[i]*pw1[pri[j]]%mod;
		inv[i]=1ull*(mod-mod/i)*inv[mod%i]%mod;pw2[i]=pw2[i-1]*(k-i+1ull)%mod;ifac[i]=1ull*ifac[i-1]*inv[i]%mod;
	}
}
inline ui S(const ui&m){
	ui i,ans(0);
	for(i=1;i<=k;++i);
	for(i=0;i<=m;++i)ans=(ans+1ull*(m-i&1?mod-pw1[i]:pw1[i])*pw2[i]%mod*ifac[i])%mod;
	return 1ull*ans*ifac[m]%mod;
}
signed main(){
	ui i,j,c,sum(0);scanf("%u%u",&n,&k);sieve();
	for(i=1;i<=n;++i)scanf("%u",&c),sum=sum+c>=mod?sum+c-mod:sum+c;c=S(k);
	for(i=1;i<=k;++i)pw1[i]=1ull*pw1[i]*inv[i]%mod;printf("%u",1ull*sum*(c+(n-1ull)*S(k)%mod)%mod);
}
posted @ 2022-07-18 19:21  Prean  阅读(25)  评论(0编辑  收藏  举报
var canShowAdsense=function(){return !!0};