题目链接
题目描述
给定 nnn 种颜色的球,每种球有 aia_iai 个,对这些球执行以下操作:
- 有顺序地任意取两个球,将第二个球涂上第一个球的颜色,重复该操作至所有球颜色相同。
求期望操作次数,对 109+710^9+7109+7 取模。
数据范围:n≤2500n\le 2500n≤2500,1≤ai≤1051\le a_i\le 10^51≤ai≤105。
Solution
- 设 fif_ifi 表示当前有 iii 个球,将所有球变为该颜色的期望次数,sss 表示球的总数,ppp 表示当前取出的两个球第一个与最终颜色相同,第二个与最终颜色不同的概率。
根据题意,有 p=i×(s−i)s×(s−1)p=\frac{i\times(s-i)}{s\times(s-1)}p=s×(s−1)i×(s−i)fi=p×fi−1+p×fi+1+(1−2p)×fi+vf_i=p\times f_{i-1}+p\times f_{i+1}+(1-2p)\times f_i+vfi=p×fi−1+p×fi+1+(1−2p)×fi+v其中 vvv 为这一步操作对最终答案的贡献,也就是该颜色成为最终颜色的概率。 - 设 gig_igi 表示当前颜色成为最终颜色的概率,有 g0=0g_0=0g0=0,g1=1g_1=1g1=1,且 gi=p×gi−1+p×gi+1+(1−2p)×gig_{i}=p\times g_{i-1}+p\times g_{i+1}+(1-2p)\times g_igi=p×gi−1+p×gi+1+(1−2p)×gi。
转化可得 gi−gi−1=gi+1−gig_i-g_{i-1}=g_{i+1}-g_{i}gi−gi−1=gi+1−gi,等差数列求和可得 gi=isg_i=\frac{i}{s}gi=si,即 v=isv=\frac{i}{s}v=si。 - 那么现在有fi=p×fi−1+p×fi+1+(1−2p)×fi+isf_i=p\times f_{i-1}+p\times f_{i+1}+(1-2p)\times f_i+\frac{i}{s}fi=p×fi−1+p×fi+1+(1−2p)×fi+si转化后有fi−fi+1=fi−1−fi+s−1s−if_{i}-f_{i+1}=f_{i-1}-f_{i}+\frac{s-1}{s-i}fi−fi+1=fi−1−fi+s−is−1
- 考虑求 f1f_1f1 和 f2f_2f2 后线性递推,由于 f0f_0f0 不存在,代入后有 f2=2f1−1f_2=2f_1-1f2=2f1−1。
f1=f1−fs=∑i=2sfi−1−fi=(s−1)×(f1−f2)+∑i=2s−1s−1s−i×(s−i)=(s−1)×(1−f1)+(s−1)×(s−2)\begin{aligned}f_1&=f_1-f_s\\ &=\sum_{i=2}^{s}{f_{i-1}-f_{i}}\\ &=(s-1)\times(f_1-f_2)+\sum_{i=2}^{s-1}{\frac{s-1}{s-i}\times(s-i)}\\&=(s-1)\times(1-f_1)+(s-1)\times(s-2)\end{aligned}f1=f1−fs=i=2∑sfi−1−fi=(s−1)×(f1−f2)+i=2∑s−1s−is−1×(s−i)=(s−1)×(1−f1)+(s−1)×(s−2) - 所以f1=(s−1)2sf_1=\frac{(s-1)^2}{s}f1=s(s−1)2线性递推即可求解,答案为 ∑i=1nfai\sum_{i=1}^{n}{f_{a_{i}}}∑i=1nfai。
Code
#include<cstdio>
using namespace std;
const int maxn=100010,MLY=1000000007;
int f[maxn],n,a[maxn],s,ans;
inline int power(int a,int b){int ans=1;while(b){if(b&1)ans=1ll*ans*a%MLY;a=1ll*a*a%MLY;b>>=1;}return ans;
}
int main(){scanf("%d",&n);for(int i=1;i<=n;++i)scanf("%d",&a[i]),s+=a[i];f[1]=(s-1ll)*(s-1)%MLY*power(s,MLY-2)%MLY;f[2]=(2ll*f[1]-1+MLY)%MLY;for(int i=2;i<100000;++i)f[i+1]=((2ll*f[i]-f[i-1]-(s-1ll)*power(s-i,MLY-2))%MLY+MLY)%MLY;for(int i=1;i<=n;++i)ans=(ans+f[a[i]])%MLY;printf("%d",ans);return 0;
}