很好的一道题,有概率从$a$数组中取出子序列。
将子序列排序,这个子序列的权值就是=$\sum_{i=1}^{n-1}a[i]*a[i+1]$
求期望权值。
先将$a$排序
对于一对$(i,j)$贡献=$\sum a_ia_j2^{n-(j-i+1)}$
没有查询的做法只需要
预处理前缀和就好了。
可以看到比$j$小的$(a_i*2^{i-1})$会对$j$产生影响。
设置一个线段树
- $co=num[l,r]$
- $lval=\sum_i^{co_{ls}}(a_i*2^{i-1})$
- $rval=\sum_i^{co_{rs}}(a_i*2^{-j})$
- $val=\sum_{i<j} (a_i2^{i-1})(a_j2^{-j})$
假设左右已经记录好$lval,rval,val,co$
- 考虑$val$,左右两端都已经将自己的$val$,即$j>i$,每个的贡献。那么合并的时候还差右儿子中的数对左儿子中的的贡献。$val=val[ls]+val[rs]+lvar[ls]rval[rs]2^{-co[ls]}$
- $lval$和$rval$的更新注意的是右儿子会发生的值会$*2^{co[ls]}$或$2^{-co[ls]}$
然后这道题线段树其实在维护一个区间,所有需要先把所有值读入,排好序确定之间的关系。查询的时候只需要把对于在线段树上维护那个区间的点删除或者修改即可
代码
1 |
|