Description
有n个带权物品,要把它们分成k个集合
定义一个分法的权值为每个集合的大小*集合内权值之和
问所有分法权值之和
Solution
一开始没看到要乘上一个集合大小。。以为是sb题
讲一个头铁娃的做法
显然每个物品对答案贡献的系数都是一样的。考虑枚举一个物品所在集合的大小s,那么有
∑
s
=
1
n
s
(
n
−
1
s
−
1
)
{
n
−
s
k
−
1
}
\sum_{s=1}^{n}{s\binom{n-1}{s-1}\begin{Bmatrix}n-s\\k-1\end{Bmatrix}}
s=1∑ns(s−1n−1){n−sk−1}
这个柿子还是很直观的
跳过一些中间拆掉斯特林数和交换枚举的步骤,我们不难得到这样一个柿子
∑
i
=
0
k
−
1
(
−
1
)
i
(
k
−
i
−
1
)
!
i
!
∑
s
=
1
n
s
(
n
−
1
s
−
1
)
(
k
−
i
−
1
)
n
−
s
\sum_{i=0}^{k-1}{\frac{{\left(-1\right)}^{i}}{{\left(k-i-1\right)}!{i}!}\sum_{s=1}^{n}{s\binom{n-1}{s-1}{\left(k-i-1\right)}^{n-s}}}
i=0∑k−1(k−i−1)!i!(−1)is=1∑ns(s−1n−1)(k−i−1)n−s
我们不妨分析后面那个Σ的内容
找不同环节到了。。一个神仙操作就是
∑
s
=
1
n
s
(
n
−
1
s
−
1
)
(
k
−
i
−
1
)
n
−
s
=
∑
s
=
1
n
(
s
−
1
)
(
n
−
1
s
−
1
)
(
k
−
i
−
1
)
n
−
s
+
∑
s
=
1
n
(
n
−
1
s
−
1
)
(
k
−
i
−
1
)
n
−
s
\sum_{s=1}^{n}{s\binom{n-1}{s-1}{\left(k-i-1\right)}^{n-s}}=\sum_{s=1}^{n}{\left(s-1\right)\binom{n-1}{s-1}{\left(k-i-1\right)}^{n-s}}+\sum_{s=1}^{n}{\binom{n-1}{s-1}{\left(k-i-1\right)}^{n-s}}
s=1∑ns(s−1n−1)(k−i−1)n−s=s=1∑n(s−1)(s−1n−1)(k−i−1)n−s+s=1∑n(s−1n−1)(k−i−1)n−s
注意到
k
(
n
k
)
=
n
(
n
−
1
k
−
1
)
k\binom{n}{k}=n\binom{n-1}{k-1}
k(kn)=n(k−1n−1),于是
(
n
−
1
)
∑
s
=
1
n
(
n
−
2
s
−
2
)
(
k
−
i
−
1
)
n
−
s
+
∑
s
=
1
n
(
n
−
1
s
−
1
)
(
k
−
i
−
1
)
n
−
s
\left(n-1\right)\sum_{s=1}^{n}{\binom{n-2}{s-2}{\left(k-i-1\right)}^{n-s}+\sum_{s=1}^{n}{\binom{n-1}{s-1}{\left(k-i-1\right)}^{n-s}}}
(n−1)s=1∑n(s−2n−2)(k−i−1)n−s+s=1∑n(s−1n−1)(k−i−1)n−s
又注意到
k
n
=
(
k
−
1
+
1
)
n
=
∑
i
=
0
n
(
n
i
)
(
k
−
1
)
n
−
i
k^n={\left(k-1+1\right)}^n=\sum_{i=0}^{n}{\binom{n}{i}{\left(k-1\right)^{n-i}}}
kn=(k−1+1)n=∑i=0n(in)(k−1)n−i,所以我们可以把上面的柿子化成
(
n
−
1
)
(
k
−
i
)
n
−
2
+
(
k
−
i
)
n
−
1
\left(n-1\right){\left(k-i\right)}^{n-2}+{\left(k-i\right)}^{n-1}
(n−1)(k−i)n−2+(k−i)n−1
然后往回带,就可以做到
O
(
n
log
n
)
O(n\log n)
O(nlogn)求系数了,最后乘上权值之和就是答案
累死我了。。
Code
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <algorithm>
#include <vector>
#include <queue>
#include <map>
#define rep(i,st,ed) for (int i=st;i<=ed;++i)
#define drp(i,st,ed) for (int i=st;i>=ed;--i)
#define fill(x,t) memset(x,t,sizeof(x))
#define copy(x,t) memcpy(x,t,sizeof(x))
#define fi first
#define se second
typedef std:: pair <int,int> pair;
typedef long double ld;
typedef long long LL;
const int INF=0x3f3f3f3f;
const int MOD=1e9+7;
const int ny2=(MOD+1)/2;
const int N=200005;
const ld pi=acos(-1);
const ld e=exp(1);
const ld eps=1e-8;
LL inv[N],fac[N],w[N];
int read() {
int x=0,v=1; char ch=getchar();
for (;ch<'0'||ch>'9';v=(ch=='-')?(-1):v,ch=getchar());
for (;ch<='9'&&ch>='0';x=x*10+ch-'0',ch=getchar());
return x*v;
}
LL ksm(LL x,LL dep) {
LL res=1;
for (;dep;dep>>=1,x=x*x%MOD) {
(dep&1)?(res=res*x%MOD):0;
}
return res;
}
int main(void) {
int n=read(),k=read();
LL sum=0,T=0;
fac[0]=fac[1]=inv[0]=inv[1]=1;
rep(i,2,n-1) {
fac[i]=fac[i-1]*i%MOD;
inv[i]=inv[MOD%i]*(MOD-MOD/i)%MOD;
}
rep(i,2,n-1) inv[i]=inv[i-1]*inv[i]%MOD;
rep(i,1,n) {
LL tmp=read();
sum+=tmp; (sum>=MOD)?(sum-=MOD):0;
}
if (n==1) return 0&printf("%lld\n", sum);
rep(i,0,k-1) {
LL tmp=inv[i]*inv[k-i-1]%MOD*ksm(k-i,n-2)%MOD*(n+k-i-1)%MOD;
if (i&1) T+=MOD-tmp;
else T+=tmp;
(T>=MOD)?(T-=MOD):0;
}
printf("%lld\n", sum*T%MOD);
return 0;
}