P10173题解
P10173 maxiMINImax
思路:
题目要求对符合要求的区间进行计数,而判断一个区间是否符合要求,只和这个区间的最大/最小值有关,所以考虑每个 \(a_i\) 能在哪些区间成为最大/最小值,然后枚举中间的区间最小值,用树状数组对两侧区间的信息整合。
单调队列处理出每个 \(a_i\) 两侧,第一个比它大和比它小的点的下标,记为 \(lb_i,ls_i,rb_i,rs_i\),其中 \(l,r\) 表示左右,\(b,s\) 表示比 \(a_i\) 大/小。
注:若找不到比 \(a_i\) 大/小的,即 \(a_i\) 左/右的数全都比 \(a_i\) 小/大,则记为数列边界,左侧为 \(0\) ,右侧为 \(n+1\) 。
计算以 \(a_i\) 为最小值的区间数量 \(x_i=(i-ls_i)(rs_i-i)\) ,以 \(a_i\) 为最大值则记为 \(y_i=(i-lb_i)(rb_i-i)\)。
所求 \(ans\) 即可表示为:
\[ ans=\sum_{1<i<n}\sum_{1\le j<i,a_j<a_i}\sum_{i<k\le n,a_k<a_i} (a_i-a_j)(a_i-a_k)x_iy_jy_k \]
方便起见,用 \(\sum_{i},\sum_{j},\sum_{k}\) 代指 \(\sum_{1<i<n},\sum_{1\le j<i,a_j<a_i},\sum_{i<k\le n,a_k<a_i}\),亦即枚举符合条件的三区间极值。
- 注:由于 \(a_i>a_j,a_k\),则“以 \(a_i\) 为最小值的区间”,与“以 \(a_j,a_k\) 为最大值的区间”不可能重合,不影响计数。
\[ \begin{aligned} ans &=\sum_{i}\sum_{j}\sum_{k} (a_i-a_j)(a_i-a_k)x_iy_jy_k\\ &=\sum_{i}x_i\sum_{j}\sum_{k} \left[a_i^2-a_i\left(a_j+a_k\right)+a_ja_k\right]y_jy_k\\ &=\sum_{i}x_i \left[ a_i^2\sum_{j}\sum_{k}y_jy_k- a_i\sum_{j}\sum_{k} \left(a_j+a_k\right)y_jy_k+ \sum_{j}\sum_{k}a_ja_ky_jy_k \right]\\ &=\sum_{i}x_i \left[ a_i^2\sum_{j}\sum_{k}y_jy_k- a_i \left( \sum_{j}\sum_{k} a_jy_jy_k+ \sum_{j}\sum_{k} a_ky_jy_k \right)+ \sum_{j}\sum_{k}a_jy_ja_ky_k \right] \end{aligned} \]
- 注意到:对于数列 \(\{a_n\},\{b_n\}\) \[\sum_{i}\sum_{j}a_ib_j=\sum_{i}\left(a_i\sum_{j}b_j\right)=\left(\sum_{i}a_i\right)\left(\sum_{j}b_j\right)\]
\[ \begin{aligned} ans &=\sum_{i}x_i \left[ a_i^2\left(\sum_{j}y_j\right)\left(\sum_{k}y_k\right)- a_i\left[ \left(\sum_{j}a_jy_j\right)\left(\sum_{k}y_k\right)+ \left(\sum_{j}y_j\right)\left(\sum_{k}a_ky_k\right) \right]+ \left(\sum_{j}a_jy_j\right)\left(\sum_{k}a_ky_k\right) \right] \end{aligned} \]
化简过程中应尽可能将 \(j,k\) 有关的项分离,使之可以被树状数组维护,即避免出现 \(\sum_{j}\sum_{k}f(j)g(k)\) 的出现。
到此为止,我们已经通过树状数组维护 \(\sum_{j}y_j,\sum_{k}y_k,\sum_{j}a_jy_j,\sum_{k}a_ky_k\) 来计算 \(ans\) 了,但是上式还可以继续化简使得代码更加简洁,记
\[ \begin{aligned} L_y&(i)&=&\sum_{j}y_j\\ R_y&(i)&=&\sum_{k}y_k\\ L_{ay}&(i)&=&\sum_{j}a_jy_j\\ R_{ay}&(i)&=&\sum_{k}a_ky_k \end{aligned} \]
则 \(ans\) 可简写为:
\[ \begin{aligned} ans &=\sum_{i}x_i \left[ a_i^2L_y(i)R_y(i)- a_i\left[L_{ay}(i)R_y(i)+L_y(i)R_{ay}(i)\right]+ L_{ay}(i)R_{ay}(i) \right] \end{aligned} \]
观察各项系数
\(L_y(i)\) \(L_{ay}(i)\) \(R_y(i)\) \(a_i^2\) \(-a_i\) \(R_{ay}(i)\) \(-a_i\) \(1\) 可因式分解
\[ \begin{aligned} ans &=\sum_{i}x_i \left[ a_iL_y(i)-L_{ay}(i) \right] \left[ a_iR_y(i)-R_{ay}(i) \right] \end{aligned} \]
在从左到右枚举 \(i\) 的同时,把树状数组当作桶数组使用,以 \(a_i\) 为关键字,把 \(y_i,a_iy_i\) 放进相应的桶里,同时支持查询 \(i\) 左/右侧比 \(a_i\) 小的 \(L,R\),就可以 \(O(n\log n)\) 地计算 \(ans\) 了。
代码
1 |
|