单调栈 + 二维数点.
对于一组端点 $(l,r)$ ,考虑将它们可能的贡献放到区间 $[l+1,r-1]$ 的最大值的那个位置去计算.
即,在每个位置 $i$ ,考虑它作为区间 $[l+1,r-1]$ 最大值时产生的 $p_1,p_2$ 的贡献.
利用单调栈求出 $i$ 左边第一个比它大的位置 $L$ ,右边第一个比它大的位置 $R$ .
由于 $i$ 要是区间内的最大值,所以选择的左端点 $\ge L$, 右端点 $\le R$ .
当左右端点分别选择了 $L,R$ 时,会造成 $p_1$ 的贡献.
当左端点选了 $L$ ,右端点在 $[i+1,R-1]$ 中时,或左端点在 $[L+1,i-1]$ 中,右端点选了 $R$ ,都会有 $p_2$ 的贡献.
而我们的询问是限制了左右端点的取值范围,相当于在平面上询问一个矩形内贡献之和.
每个 $i$ 的贡献是一个单点 $(L,R)$ ,以及两条线段 $(L,i+1\sim R-1),(L+1\sim i-1,R)$ .
将操作全部离线下来,用线段树在平面上二维数点即可,可以分别计算横的线段和竖的线段的贡献.
最后还要加上两个端点是相邻的情况造成的若干 $p_1$ 贡献.
时间复杂度 $O(n\log n)$ .
开始判 $R\neq n+1$ 的时候写成 $R\neq n-1$ 了,居然还过了 80 分,调了好久.
1 | //%std |