zoukankan      html  css  js  c++  java
  • 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就改回来了

  • 相关阅读:
    如何实现多个异步同步执行?
    Treap学习笔记
    实验
    bzoj2876 [NOI2012]骑行川藏(拉格朗日乘数法)
    [SCOI2007]最大土地面积(旋转卡壳)
    Splay学习笔记
    计算几何学习笔记
    [CQOI2006]凸多边形(半平面交)
    大数的乘法(C++)
    商人过河问题(DFS)
  • 原文地址:https://www.cnblogs.com/hjmmm/p/9498252.html
Copyright © 2011-2022 走看看