LOJ#2019. 「AHOI / HNOI2017」影魔
题意:
在一个序列中 如果有一个子区间
它有一个端点是区间最大值 另一个端点不是这个区间的次大值 就会有p2的贡献
它两个端点分别是最大值次大值 就会有p1的贡献
我们发现这两个条件有一个重合的部分
即区间有一个端点是最大值
再次拆分问题
如果我们只考虑这个区间的左端点是最大值
那么我们可以记录每个节点i右边第一个大于它的值的位置R[i]
那么左端点为i的满足条件的区间有[i, i], [i, i + 1], ..... , [i, R[i] - 1]
第一步展开
如果求右端点是最大值的子区间数时
记录每个数左边第一个大于它的值的位置L[i] 仿照上面的步骤即可
上述左右方向计数 [i, i]会被重复计数需要除去
现在我们可以O(n)统计总的满足至少一个端点是最大值的区间数了
你有没有犹疑过部分数据 那个p1 = 2 * p2是什么鬼?
你把右端点最大区间按[i, i], .... , [i, R[i]]计数
左端点最大区间同理 会发现满足p2条件区间刚好被计数了一次
满足p1条件的区间刚好被计数了两次
我们只要在原来答案的起初上+ p1 - 2p2就改回来了