zoukankan      html  css  js  c++  java
  • [JZOJ5232] 【NOIP2017模拟A组模拟8.5】带权排序

    题目

    在这里插入图片描述

    题目大意

    有一个数列AA,数列上的每个数都是在[li,ri][l_i,r_i]范围内随机的数。
    将这个数列进行稳定排序,得到每个位置在排序后的排名pip_i
    f(A)=sipif(A)=sum s_ip_i,求E(f(A))E(f(A))


    思考历程

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


    正解

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


    代码

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

  • 相关阅读:
    电脑连不上网
    decompiler of java
    emmmmmmmmmmmmmmmmmm01
    WEB-INF
    tan?
    spring配置
    maven安装和使用前的几个点
    ※剑指offer系列29:两个链表的第一个公共结点
    剑指offer系列28:数组中的逆序对
    剑指offer系列27:第一个只出现一次的字符
  • 原文地址:https://www.cnblogs.com/jz-597/p/11145240.html
Copyright © 2011-2022 走看看