zoukankan      html  css  js  c++  java
  • CF1290E Cartesian Tree

    考虑笛卡尔树的意义:

    一个点在笛卡尔树中的子树,代表以他为最小/最大值的区间。
    所以一个点的子树大小,一定是类似到达序列边界或者被一个比他更大的数隔离。

    考虑记录 \(l_i,r_i\) 为第 \(i\) 个数往前的第一个比他大数位置,以及往后第一个比他大的数位置。

    则该的子树大小为为 \(r_i - l_i + 1\)

    所以所有的点答案为 \(\sum r_i - l_i + 1\)

    考虑这个数据范围,我们应该要实现一个可以支持插值,并且一次操作为 \(log\) 就能维护 \(l,r\)的数据结构。

    我们思考到,这题的一个关键性质:每次都加入一个最大的数。

    那么我们可以考虑这个数位于 \(x\),那么他对左右两边都有贡献。

    具体来说即对右边的位置 \(l_i\)\(min\),左边的位置 \(r_i\)\(max\)

    那么可以联想到吉司机线段树。

    我们拆成两颗线段树来做,一颗维护 \(l\),一颗维护\(r\)即可。

    同时注意到,每次插入,都会让右侧的 \((l,r) \to (l+1,r + 1)\)

    我们需要做的操作有:区间取 \(min/max\),区间加,查全局和单点加。

    复杂度\(O(nlog^2n)\)

  • 相关阅读:
    Foundation框架中一些类的使用
    Objective-C知识总结(5)
    Javascript 严格模式详解
    JS-数组冒泡排序
    JS--垒房子
    JS-小球碰撞反弹
    Js制作的文字游戏
    JS产生随机一注彩票
    JS编写背景图切换
    JS编写全选,复选按钮
  • 原文地址:https://www.cnblogs.com/dixiao/p/15103884.html
Copyright © 2011-2022 走看看