题目大意
定义一个序列的 average 为 $\frac{最大值+最小值}{2}$。
给定一个序列 $a_1,\cdots,a_n$,有 $m$ 次询问,每次问这个区间的所有子区间的 average 期望。
$n,m \le 2 \times 10^5,\ 1 \le a_i \le 10^9$
多测,$\sum n,\sum m \le 3 \times 10^5$
8s
扯淡
考场上脑补了个 $O(m \sqrt n)$ 的只增莫队巨难写,写到最后又 WA 又 T。
第二天牛爷爷说这是个原题,上网搜了一下大家说这个题是【HNOI2016 序列】,于是就去学习了一下,老年选手被这个神奇的技巧秀得头皮发麻。。。
题解
首先 $\mathbb E[\frac{\max+\min}{2}]=\frac{\mathbb E[\max]+\mathbb E[\min]}{2}$,所以问题变成每次求一个区间所有子区间的 $\max$ 和以及 $\min$ 和。这就是【HNOI2016 序列】了。
做法多种多样,莫队和在线 $O(n \log n+m)$ 的都有,但其实本质相同的,莫队到在线也就多一步小转化而已。下面就讲在线的。
考虑这样一个数组:$f_i$ 表示右端点为 $i$、左端点 $\in [1,i]$ 的所有区间的 $\max$ 和。它的转移很简单,就是找到 $i$ 上一个比它大的数 $L_i$,那么左端点 $\le L_i$ 的区间的 $\max$ 都保持不变,左端点 $\in (L_i,i]$ 的区间的 $\max$ 等于 $a_i$,因此
这东西怎么用呢?变形得到 $f_i-f_{L_i}=a_i(i-L_i)$,也就是说,知道了 $i$ 的转移点 $L_i$,那么就知道了左端点 $\in(L_i,i]$、右端点为 $i$ 的所有区间的 $\max$ 和。
更进一步,$i$ 从 $L_i$ 转移来,$L_i$ 从 $L_{L_i}$ 转移来……这样形成一个转移路径(实际上就是以 $i$ 结尾的单调栈),在这条路径上的任何一个 $j$,都满足 $f_i-f_j$ 等于左端点 $\in(j,i]$、右端点为 $i$ 的所有区间的 $\max$ 和。
接下来就可以做这题了。
询问一个区间 $[l,r]$ 的所有子区间的 $\max$ 和,先找到这个区间的最大值所在位置 $mx$,那么凡是左端点 $\in [l,mx]$、右端点 $\in (mx,r]$ 的子区间,最大值都是 $a_{mx}$。因此问题转化成 $[l,mx)$、$(mx,r]$ 的子问题。
考虑 $(mx,r]$,重要的性质是,$mx$ 一定在 $r$ 的转移路径上,因此 $f_r-f_{mx}$ 就是左端点 $\in (mx,r]$、右端点为 $r$ 的子区间的 $\max$ 和;同理,$mx$ 一定也在 $r-1$ 的转移路径上,所以 $f_{r-1}-f_{mx}$ 就是左端点 $\in (mx,r-1]$、右端点为 $r-1$ 的子区间的 $\max$ 和……
因此 $(mx,r]$ 的贡献就是
所以求个 $f$ 的前缀和就做好了。
同理可求 $[l,mx)$ 的贡献,以及 $\min$ 和。
时间复杂度,预处理 rmq 需要 $O(n \log n)$,预处理 $f$ 需要 $O(n)$,每个询问是 $O(1)$ 的,因此是 $O(n \log n + m)$。
代码
1 |
|