[JZOJ5232] 【NOIP2017模拟A组模拟8.5】带权排序

题目

在这里插入图片描述

题目大意

有一个数列 A A A,数列上的每个数都是在 [ l i , r i ] [l_i,r_i] [li,ri]范围内随机的数。
将这个数列进行稳定排序,得到每个位置在排序后的排名 p i p_i pi
f ( A ) = ∑ s i p i f(A)=\sum s_ip_i f(A)=sipi,求 E ( f ( A ) ) E(f(A)) E(f(A))


思考历程

这种恶心的概率题根本就不知道该怎么思考好吗!
于是打了个暴力,就是枚举所有的情况,然后直接计算。
可是最后不知道为什么爆0了……


正解

E ( f ( A ) ) = ∑ s i E ( p i ) E(f(A))=\sum s_i E(p_i) E(f(A))=siE(pi)
所以我们只需要求出 p i p_i pi的期望值就好了。
显然 p i = ∑ j ≤ i ∣ a j ≤ a i ∣ + ∑ j &gt; i ∣ a j &lt; a i ∣ p_i=\sum_{j\leq i} |a_j \leq a_i|+\sum_{j&gt;i} |a_j&lt; a_i| pi=jiajai+j>iaj<ai
左右两边是类似的,下面只考虑左边的情况。
a i = x a_i=x ai=x。对于每个位置 j j j,有三种情况:
1、当 x &lt; l j x&lt;l_j x<lj时,位置 j j j作出的贡献为 0 0 0
2、当 l j ≤ x ≤ r j l_j \leq x \leq r_j ljxrj时,位置 j j j做出的贡献为 x − l i + 1 r i − l i + 1 \frac{x-l_i+1}{r_i-l_i+1} rili+1xli+1
3、当 x &gt; r j x&gt;r_j x>rj时,位置 j j j作出的贡献为 1 1 1
不解释……
可以将其转化成一个分段函数的图像来理解一下,前后两段都是与 x x x轴平行的线,中间的那段是一段一次函数的图像。
将所有 j j j的函数全部加起来,枚举 x x x,就可以计算 E ( p i ) E(p_i) E(pi)
接下来我们考虑的问题是如何将所有 j j j的函数叠加起来,并且能够快速查询一段区间内的和。
在叠加之后,函数长得一定很奇怪……所以不能用数学方法。
考虑使用线段树,用线段树来维护这些东西。
现在有一个奇怪的操作,在线段树内的一段区间上加某段一次函数的图像。
换个说法就是给这段区间加上一个等差数列。
这个怎么维护呢?
我们发现最重要的一点就是标记,关键是如何维护标记。
合并标记的时候,两段一次函数的都在同一段区间内,仔细想想是可以合并的。
一次函数的普遍形式就是 y = k x + b y=kx+b y=kx+b,合并起来之后就是 y = ( k 1 + k 2 ) x + ( b 1 + b 2 ) y=(k_1+k_2)x+(b_1+b_2) y=(k1+k2)x+(b1+b2)。所以可以简单粗暴地相加。
这样维护标记的问题就解决了,整个区间的值都可以维护。
下一个问题就是如何快速地询问,直接维护和就好,在修改的时候加上等差数列的和(千万不要告诉我你不会等差数列求和)。
算法的核心就完成了。
所以我们维护一个这样的线段树,然后从左往右扫,将当前点的贡献(也就是那个分段函数)加入线段树当中,然后区间询问当前点取值范围这一区间内的和,计算 E ( p i ) E(p_i) E(pi)
再从右往左扫,实际上是类似的。


代码

我才不会告诉你我先打了博客再打代码……

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值