题目大意: 给出一个长度为 n n n 的序列,进行 k k k 次操作,每次随机选取一个 a i a_i ai,让答案加上 a a a 序列中的其他数的乘积,然后让 a i − 1 a_i-1 ai−1,问最后答案的期望。
题解
膜拜往日的神仙 OZY。
与样例快乐van耍之后,发现答案与操作顺序无关,只与每个位置被操作的次数有关。
那么不妨认为每个数都是被连续操作的,那么我们可以把一次操作的贡献看成 ( a x ∏ i ≠ x a i ) − ( ( a x − 1 ) ∏ i ≠ x a i ) (a_x\prod\limits_{i\ne x}a_i)-((a_x-1)\prod\limits_{i\ne x}a_i) (axi=x∏ai)−((ax−1)i=x∏ai),那么把 s s s 次对 x x x 的连续操作加起来,就得到了 ( a x ∏ i ≠ x a i ) − ( ( a x − s ) ∏ i ≠ x a i ) (a_x\prod\limits_{i\ne x}a_i)-((a_x-s)\prod\limits_{i\ne x}a_i) (axi=x∏ai)−((ax−s)i=x∏ai)。
同样的,把 k k k 次操作后的贡献加起来,就能得到 ∏ a i − ∏ ( a i − b i ) \prod a_i-\prod (a_i-b_i) ∏ai−∏(ai−bi),其中 b i b_i bi 是第 i i i 个数被操作的次数。
前面一项是固定的,只需要求后面一项的期望即可。
对每一个数 a j a_j aj 造一个生成函数, x i x^i xi 项表示这个数被操作 i i i 次,系数就是被操作 i i i 次的贡献,即 ( a j − i ) (a_j-i) (aj−i)。
考虑到所有操作形成一个排列,一个 b b b 序列可能对应多种操作方式,所以用 E G F EGF EGF,有 f j = ∑ i = 0 ( a j − i ) x i i ! f_j=\sum\limits_{i=0}(a_j-i)\dfrac {x^i} {i!} fj=i=0∑(aj−i)i!xi。
那么将所有 f j f_j fj 乘起来, x k x^k xk 那一项的系数就是答案。但是 x k x^k xk 下面有个 k ! k! k!,系数乘过来的时候得到的是 x k x^k xk 的系数,而不是 x k k ! \dfrac {x^k} {k!} k!xk 的系数,所以这一项的系数还要乘以 k ! k! k!,才是我们想要的 x k k ! \dfrac {x^k} {k!} k!xk 的系数。
并且,由于需要求的是期望,而这一项的系数是所有方案的和,所以还要除以总方案数 n k n^k nk。
所以,最终的柿子为:
k
!
n
k
∏
j
=
1
n
(
∑
i
=
0
(
a
j
−
i
)
x
i
i
!
)
=
k
!
n
k
∏
j
=
1
n
(
∑
i
=
0
a
j
x
i
i
!
−
∑
i
=
0
i
x
i
i
!
)
=
k
!
n
k
∏
j
=
1
n
(
a
j
e
x
−
∑
i
=
0
x
i
(
i
−
1
)
!
)
=
k
!
n
k
∏
j
=
1
n
(
a
j
e
x
−
∑
i
=
0
x
x
i
i
!
)
=
k
!
n
k
∏
j
=
1
n
(
a
j
−
x
)
e
x
=
k
!
n
k
e
n
x
∏
j
=
1
n
(
a
j
−
x
)
\begin{aligned} &~~~~~\frac {k!} {n^k}\prod_{j=1}^n(\sum_{i=0}(a_j-i)\frac {x^i} {i!})\\ &=\frac {k!} {n^k}\prod_{j=1}^n(\sum_{i=0}a_j\frac {x^i} {i!}-\sum_{i=0}i\frac {x^i} {i!})\\ &=\frac {k!} {n^k}\prod_{j=1}^n(a_je^{x}-\sum_{i=0}\frac {x^i} {(i-1)!})\\ &=\frac {k!} {n^k}\prod_{j=1}^n(a_je^{x}-\sum_{i=0} x \frac {x^i} {i!})\\ &=\frac {k!} {n^k}\prod_{j=1}^n(a_j-x)e^{x}\\ &=\frac {k!} {n^k} e^{nx} \prod_{j=1}^n(a_j-x)\\ \end{aligned}
nkk!j=1∏n(i=0∑(aj−i)i!xi)=nkk!j=1∏n(i=0∑aji!xi−i=0∑ii!xi)=nkk!j=1∏n(ajex−i=0∑(i−1)!xi)=nkk!j=1∏n(ajex−i=0∑xi!xi)=nkk!j=1∏n(aj−x)ex=nkk!enxj=1∏n(aj−x)
后面的 ∏ \prod ∏ 可以 n 2 n^2 n2 暴力求,设 f [ i ] f[i] f[i] 表示求完之后的多项式的 x i x^i xi 项的系数。
由于需要求第 k k k 项的系数,而后面的 ∏ \prod ∏ 得到的是个 n n n 次的多项式,所以只需要 e n x e^{nx} enx 后 n n n 项的系数。
最后的答案就是:
a
n
s
=
k
!
n
k
∑
i
=
0
min
(
n
,
k
)
f
[
i
]
×
n
k
−
i
(
k
−
i
)
!
=
∑
i
=
0
min
(
n
,
k
)
f
[
i
]
×
(
k
−
i
+
1
)
(
k
−
i
+
2
)
.
.
.
k
n
i
\begin{aligned} ans&=\frac {k!} {n^k} \sum_{i=0}^{\min(n,k)} f[i]\times \frac {n^{k-i}} {(k-i)!}\\ &=\sum_{i=0}^{\min(n,k)} f[i]\times \frac {(k-i+1)(k-i+2)...k} {n^i} \end{aligned}
ans=nkk!i=0∑min(n,k)f[i]×(k−i)!nk−i=i=0∑min(n,k)f[i]×ni(k−i+1)(k−i+2)...k
代码如下:
#include <cstdio>
#define mod 1000000007
int n,k,f[5010],ans=0;
int ksm(int x,int y){int re=1;for(;(y&1?re=1ll*re*x%mod:0),y;y>>=1,x=1ll*x*x%mod);return re;}
inline int min(int x,int y){return x<y?x:y;}
#define inv(x) ksm(x,mod-2)
int main()
{
scanf("%d %d",&n,&k);f[0]=1;
for(int i=1,x;i<=n;i++){
scanf("%d",&x);for(int j=i;j>0;j--)
f[j]=(1ll*f[j]*x%mod-f[j-1]+mod)%mod;f[0]=1ll*f[0]*x%mod;
}
for(int i=0,fac=1,n_=1;i<=min(n,k);i++){
ans=(ans+1ll*f[i]*fac%mod*inv(n_)%mod)%mod;
fac=1ll*fac*(k-i)%mod;n_=1ll*n_*n%mod;
}
printf("%d",(f[0]-ans+mod)%mod);
}