P2221 高速公路 线段树 + 期望

Posted lasomisolaso~

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P2221 高速公路 线段树 + 期望相关的知识,希望对你有一定的参考价值。

题目大意:

题目链接
给出一个序列 A [ ] A[ ] A[],初始值为0。
有一个问题:
给定 l , r l,r lr,在第 l l l个到第 r r r个数之间等概率随机的挑选两个不同的数 a , b a, b a,b, 那么 a , b a,b a,b之间的区间和的期望值是多少。
有以下两种操作:
C l r v 表示区间从 l l l r r r的值增加 v v v
Q l r 回答上述问题。

思路:

题目中的 l , r l,r l,r表示节点,在这里我们直接用 l , r l,r l,r表示节点之间的路,那么我们进行操作之间要把 − − r --r r,才能让节点对应成节点之间的路,具体细节参看主函数。

容易想到暴力算期望的方法,每个区间被取到的概率为: 1 C r − l + 1 2 \\frac1C_r - l + 1^2 Crl+121
那么期望就是 : 1 C r − l + 1 2 ∗ ∑ i = l r ∑ j = l r ( i , j 区 间 和 ) \\frac1C_r - l + 1^2 * \\sum_i = l ^ r\\sum_j = l^r (i,j区间和) Crl+121i=lrj=lr(i,j)
显然这个式子不太容易计算。
我们考虑每个区间对期望的贡献: ( A [ a ] + A [ a + 1 ] + . . . + A [ b ] ) ∗ 1 C r − l + 2 2 (A[a] + A[a + 1] + ...+A[b]) * \\frac1C_r - l + 2^2 (A[a]+A[a+1]+...+A[b])Crl+221

我们发现只要 A [ i ] A[i] A[i]这个元素处于一个区间中,它就会对期望贡献 A [ i ] ∗ 1 C r − l + 2 2 A[i] * \\frac1C_r - l + 2^2 A[i]Crl+221
想到这儿,我们就可以从每一个元素来考虑这个问题,我们只需要计算出多少个区间包含 A [ i ] A[i] A[i], 然后包含 A [ i ] A[i] A[i]的区间个数乘 A [ i ] ∗ 1 C r − l + 2 2 A[i] * \\frac1C_r - l + 2^2 A[i]Crl+221,即是 A [ i ] A[i] A[i]对期望的贡献值。我们一次考虑区间内的每一个元素即可。

根据组合数学的知识,我们可以知道,包含 A [ i ] A[i] A[i]的区间个数为
( i − l + 1 ) ∗ ( r − i + 1 ) (i - l + 1) * (r - i + 1) (il+1)(ri+1)

那么我们要求的最后的答案就是:
( ∑ i = l r ( i − l + 1 ) ∗ ( r − i + 1 ) ∗ A [ i ] ) ∗ 1 C r − l + 2 2 (\\sum_i = l ^ r (i - l + 1) * (r - i + 1) * A[i] ) * \\frac1C_r - l + 2^2 (i=lr(il+1)(ri+1)A[i])Crl+221

那么接下来的问题就是上面式子的左半部分怎么求的问题:
我们将累加符号中的式子展开变成:
( 1 + r − l − l ∗ r + i ∗ ( l + r ) − i 2 ) ∗ A [ i ] (1 + r - l - l * r + i * (l + r) - i^2) * A[i] (1+rllr+i(l+r)i2)A[i]
我们只需要在线段树中维护三个量: A [ i ] A[i] A[i]的区间和, i ∗ A [ i ] i*A[i] iA[i]的区间和, i 2 ∗ A [ i ] i^2 * A[i] i2A[i]的区间和即可通过线性的组合得到上面的式子。

还需要注意的一点是区间修改的操作,对于维护的第一个值来说就是普通的修改。
而对于第二个值来说,区间增加的值是 a d d ∗ ( l + l + 1 + l + 2 + . . . + r ) add*(l + l+ 1 + l + 2 +...+r) add(l+l+1+l+2+...+r),乘的是一个等差数列,也就是 a d d ∗ ( l + r ) ∗ ( r − l + 1 ) / 2 add*(l + r) * (r - l + 1) / 2 add(l+r)(rl+1)/2
对于第三个值来说,区间增加的值是 a d d ∗ ( l 2 + ( l + 1 ) 2 + . . . + r 2 ) add*(l^2+(l + 1)^2 + ...+r^2) add(l2+(l+1)2+...+r2),对于右半部分我们预处理出 i 2 i^2 i2的前缀和,那么上式就变成 a d d ∗ ( p r e [ r ] − p r e [ l − 1 ] ) add*(pre[r]-pre[l - 1]) add(pre[r]pre[l1])
线段树部分完成,具体的细节可以看代码。

代码:

/**
* Author : Xiuchen
* Date : 2020-02-29-18.40.16
* Description : 高速公路
*/
#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3,"Ofast","inline")
#include<cstdio>
#include<cstring>
#include<string>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#include<cmath>
#include<math.h>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3fLL;
const int maxn = 1e5 + 100;
ll gcd(ll a, ll b)
    return b ? gcd(b, a % b) : a;

struct SegmentTree
    ll sum[

以上是关于P2221 高速公路 线段树 + 期望的主要内容,如果未能解决你的问题,请参考以下文章

洛谷P2221 [HAOI2012]高速公路

神奇脑洞题解——HAOI2012高速公路(数学期望,线段树)

Bzoj 2752 高速公路 (期望,线段树)

JZYZOJ1527 [haoi2012]高速公路 线段树 期望

BZOJ 2752 [HAOI2012]高速公路(road) | 线段树 期望

HAOI2012高速公路bzoj2752 (线段树,数学)