CF689D Friends and Subsequences
考点
- 线段树
- 二分
题解
1 |
|
思路
使用线段树的时间复杂度是\(n\log ^2n\),需要非常卡常才能过,建议使用ST表进行优化,毕竟只需要求区间极值而不需要动态修改。
固定左端点l
,移动右端点r
,可以发现一个数学规律:
\[
\mathop {\small{\overset{r+1}{\max}}} \limits_{i=l}\,\,a_i\,\,\geqslant
\,\,\mathop {\small{\overset{r}{\max}}} \limits_{i=l}\,\,a_i
\]
\[ \mathop {\small{\overset{r+1}{\min}}} \limits_{i=l}\,\,b_i\,\,\leqslant \,\,\mathop {\small{\overset{r}{\min}}} \limits_{i=l}\,\,b_i \]
两者结合,变成: \[
\mathop {\small{\overset{r+1}{\max}}} \limits_{i=l}\,\,a_i-\mathop
{\small{\overset{r+1}{\min}}} \limits_{i=l}\,\,b_i\,\,\geqslant \mathop
{\small{\overset{r}{\max}}} \limits_{i=l}\,\,a_i-\mathop
{\small{\overset{r}{\min}}} \limits_{i=l}\,\,b_i
\] 抽象一下,变成: \[
f\left( i+1, j+1 \right) -f\left( i, j \right) \geqslant 0
\]
也就是说,固定左端点l
,右端点r
向右移动时,f
函数的值是单调不减的。
现在的目标,是找到能让函数f
的值为0的区间有多少个。
由于存在单调性,外循环每一次固定一个l
,内循环对右端点r
进行二分,找到等于0
的左右边界即可。
0
区间的左边界:
如果f >= 0
,就向左边界移动,否则向右边界,得到左边界L
0
区间的右边界:
如果f <= 0
,就向右边界移动,否则向左边界,得到右边界R
那么本轮外循环对答案的贡献就是R - L + 1
,开启下一轮外循环