题意:
N个乒乓球权值为wi,每次等概率取出一个(不放回)直到取完,
若取出第K个,则获得这颗球左边第一个乒乓球和右边第一个乒乓球的权值的乘积
左边没有球了就获得0收益,问期望收益? N<=1e5 ,模数998244353
思路:
我们枚举wi*wj产生贡献的情况
ans= 其中pij指wi*wj产生贡献的概率
我们现在来求pij:
1.整个取球过程一共有N!种情况,那么我们就可以把取球的过程看成是其中一种排列
2.对于排列X,wi*wj要做出贡献就必须ij之间的k个球在ij的左边:2!*k!
其中k=j-i-1;
3.剩下n-k-2个球顺序对结果无影响,所以(n-k-2)个球可以任意一处插入k+2个球中
方案数为(k+3)*(k+4)*…..n ,如下图
结合2,3->概率为1/n! [2*n! /(j-i)*(j-i+1)]
接下来就是化简公式 ->
令k=j-i -> i=j-k ->
交换jk求和顺序: ->
至此,后面的sum可以用NTT(nlogn)预处理出来
求ans只要O(n*1) 预处理逆元O(n),总复杂度O(nlogn)
核心代码:
//3.NTT 灵活操作 ai bi的表达式
for (int i=2;i<E;++i) a[i]=1ll*inv[i+1]*inv[i]%mod*2%mod;
for (int i=1;i<=E;++i) b[i]=ww[i];
//4.NTT 固定操作 ai卷积bi
//也就是(a0+a1x+a2x^2...)*(b0+b1x+b2x^2....)=(c0+c1x+c2x^2....),
//其中ck=sum_{j=0...k}aj*b(k-j)
//也就是说求sum_{i=0~n}sum_{j=0~i}aj*b(i-j)可以nlogn 求出来
ntt(a,1);ntt(b,1);
for (int i=0;i<=len;++i) a[i]=1ll*a[i]*b[i]%mod;
ntt(a,-1);
//5.NTT 非固定操作 计算求和表达式的答案ans
for (int i=3;i<=E;++i) (ans+=1ll*ww[i]*a[i]%mod)%=mod;
printf("%d\n",ans);