题目分析
假设拿到的第一张牌的费用是 $i$,牌库中费用 $<i$ 的有 $x$ 张,费用 $>i$ 大的有 $y$ 张;
如果 $x<=y$,那就需要猜 “$greater$”;
如果 $x> y$,那就需要猜 “$smaller$”;
开一个权值线段树,$a_i$ 表示费用为 $i$ 的有多少张,需要确定一个中值 $mid$,当 $i<=mid$ 时猜 “$greater$”, $i>mid$ 时猜 “$smaller$”;
考虑抽到第一张牌费用为 $i$ 时,此时抽这张牌的概率 $P = \frac{a_i}{sum}$,$sum$ 为总牌数:
当 $i<=mid$ 时,在剩下的牌中选择到费用 $j>i$ 的概率是 $\frac{ \sum_{j>i}a_j }{ sum-1 }$,则 $P = \frac{ a_i\sum_{j>i}a_j }{ sum(sum-1) }$;
当 $i>mid$ 时,在剩下的牌中选择到费用 $j<i$ 的概率是 $\frac{ \sum_{j<i}a_j }{ sum-1 }$,则 $P = \frac{ a_i\sum_{j<i}a_j }{ sum(sum-1) }$;
那么对于总概率 $P = [\sum_{i<=mid}a_i\sum_{j>i}a_j + \sum_{i>mid}a_i\sum_{j<i}a_j] / [sum(sum-1)] $;
对于该公式的 $a_ia_j$并不好维护,所以考虑相反的方式计算 $P$ 值;
当 $i<=mid$ 时,在剩下的牌中选择费用 $j<=i$;
当 $i>mid$ 时,在剩下的牌中选择费用 $j>=i$;
于是计算的总概率 $P = 1 - [\sum_{i<=mid}a_i[(\sum_{j<=i}a_j)-1] + \sum_{i>mid}a_i[(\sum_{j>=i}a_j)-1]] / [sum(sum-1)] $;
(这里的 $-1$ 是指选取第一张牌所以 $-1$ );
其中公式化简后有 $\sum_{}a_i\sum_{}a_j$ 与 $\sum_{}a_i$,就是需要维护区间和以及区间两两乘积和;
如何维护
假设某根节点 $rt$ 的左右孩子节点 $ls,rs$,已经维护好了他们的区间和 $sum$ 以及区间两两乘积和 $mulsum$,那么根节点的信息如此:$${ ls.sum+rs.sum, ls.mulsum+rs.mulsum+ls.sum*rs.sum }$$
就如 $ls = {a_1+a_2, a_1^2+a_2^2+a_1a_2}$,$rs = {a_3,a_3^2}$;
$rt.mulsum = a_1^2+a_2^2+a_3^2+a_1a_2+(a_1+a_2)*(a_3)$
代码实现
1 |
|