【CF961G】Partitions 第二類斯特林數

【CF961G】Partitions

題意:給出n個物品,每一個物品有一個權值$w_i$,定義一個集合$S$的權值爲$W(S)=|S|\sum\limits_{x\in S} w_x$,定義一個劃分的權值爲$V(R)=\sum\limits_{S\in R} W(S)$。求將n個物品劃分紅k個集合的全部方案的權值和。ios

$n,k\le 2\cdot 10^5,w_i\le 10^9$spa

題解:第二類斯特林數針是太好用辣!blog

顯然每一個物品都是獨立的,因此咱們只須要處理出每一個物品被統計的次數便可,說白了就是求這個式子:get

$\sum\limits_{i=1}^niC_{n-1}^{i-1}S_{n-i}^{k-1}$string

暴力拆分斯特林數it

$\sum\limits_{i=1}^niC_{n-1}^{i-1}S_{n-i}^{k-1}\\=\sum\limits_{i=1}^niC_{n-1}^{i-1}\sum\limits_{j=0}^{k-1}{(-1)^j\over j!}{(k-j-1)^{n-i}\over (k-j-1)!}\\=\sum\limits_{j=0}^{k-1}{(-1)^j\over j!(k-j-1)!}\sum\limits_{i=1}^niC_{n-1}^{i-1}(k-j-1)^{n-i}$io

考慮後面那個東西class

$\sum\limits_{i=1}^niC_{n-1}^{i-1}(k-j-1)^{n-i}\\=\sum\limits_{i=1}^nC_{n-1}^{i-1}(k-j-1)^{n-i}+\sum\limits_{i=1}^n(i-1)C_{n-1}^{i-1}(k-j-1)^{n-i}\\=\sum\limits_{i=1}^nC_{n-1}^{i-1}(k-j-1)^{n-i}+(n-1)\sum\limits_{i=1}^nC_{n-2}^{i-2}(k-j-1)^{n-i}\\=(k-j)^{n-1}+(n-1)(k-j)^{n-2}$stream

就完事啦!gc

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
typedef long long ll;
const ll P=1000000007;
typedef long long ll;
const int maxn=300010;
int n,k;
ll sum,ans;
ll jc[maxn],jcc[maxn],ine[maxn];
inline int rd()
{
	int ret=0,f=1;	char gc=getchar();
	while(gc<'0'||gc>'9')	{if(gc=='-')	f=-f;	gc=getchar();}
	while(gc>='0'&&gc<='9')	ret=ret*10+gc-'0',gc=getchar();
	return ret*f;
}
inline ll pm(ll x,ll y)
{
	if(y<0)	return 1;
	ll z=1;
	while(y)
	{
		if(y&1)	z=z*x%P;
		x=x*x%P,y>>=1;
	}
	return z;
}
int main()
{
	n=rd(),k=rd();
	int i,j;
	for(i=1;i<=n;i++)	sum=(sum+rd())%P;
	ine[0]=ine[1]=jc[0]=jc[1]=jcc[0]=jcc[1]=1;
	for(i=2;i<=n;i++)	ine[i]=P-(P/i)*ine[P%i]%P,jc[i]=jc[i-1]*i%P,jcc[i]=jcc[i-1]*ine[i]%P;
	for(j=0;j<=k-1;j++)
	{
		ll tmp=((j&1)?-1:1)*jcc[j]*jcc[k-1-j]%P;
		ans=(ans+tmp*pm(k-j,n-2)%P*(k-j+n-1))%P;
	}
	ans=(ans+P)%P;
	printf("%lld",ans*sum%P);
	return 0;
}
相關文章
相關標籤/搜索