P2221 高速公路 线段树 + 期望
Posted lasomisolaso~
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P2221 高速公路 线段树 + 期望相关的知识,希望对你有一定的参考价值。
题目大意:
题目链接
给出一个序列
A
[
]
A[ ]
A[],初始值为0。
有一个问题:
给定
l
,
r
l,r
l,r,在第
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
Cr−l+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区间和)
Cr−l+121∗∑i=lr∑j=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])∗Cr−l+221。
我们发现只要
A
[
i
]
A[i]
A[i]这个元素处于一个区间中,它就会对期望贡献
A
[
i
]
∗
1
C
r
−
l
+
2
2
A[i] * \\frac1C_r - l + 2^2
A[i]∗Cr−l+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]∗Cr−l+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)
(i−l+1)∗(r−i+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(i−l+1)∗(r−i+1)∗A[i])∗Cr−l+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+r−l−l∗r+i∗(l+r)−i2)∗A[i]。
我们只需要在线段树中维护三个量:
A
[
i
]
A[i]
A[i]的区间和,
i
∗
A
[
i
]
i*A[i]
i∗A[i]的区间和,
i
2
∗
A
[
i
]
i^2 * A[i]
i2∗A[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)∗(r−l+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[l−1])。
线段树部分完成,具体的细节可以看代码。
代码:
/**
* 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 高速公路 线段树 + 期望的主要内容,如果未能解决你的问题,请参考以下文章
神奇脑洞题解——HAOI2012高速公路(数学期望,线段树)
JZYZOJ1527 [haoi2012]高速公路 线段树 期望