zoukankan      html  css  js  c++  java
  • 题解 LOJ3277 「JOISC 2020 Day3」星座 3

    考虑一个区间,初始时为([1,n])。每次找出区间中楼房的最大高度(mx)。高度为(mx)的这些楼房把区间划分为了若干段,我们继续递归每一段。递归的边界是区间内所有楼房高度相同时不再递归。这样,我们就建出了一个有(O(n))个节点的树形结构,因为我们是根据区间最大值来划分区间,所以可以认为建出的树是一棵广义的笛卡尔树(虽然它并不是二叉树)。

    根据题目中“不能存在星座”的要求,发现:对于笛卡尔树的每个区间,它上方的区域(也就是下图中蓝色框框柱的区域,以下简称蓝色区域),要么一颗星星都没有,要么只保留一颗星星。因为只要数量超过(1)颗,就一定会冲突。

    (f[l,r])表示笛卡尔树上([l,r])这个节点,只考虑它的儿子蓝色区域内的星星,需要删除的星星的代价之和的最小值。

    可以发现,一个节点的各个儿子之间是互不相关的。

    每个节点的转移,分为:(1)蓝色区域内一颗星星都没有 (2)蓝色区域内只保留一颗星星,这两种情况。

    • 当蓝色区域内一颗星星都没有时,我们只需要把各个儿子的(f)值相加,再加上删除蓝色区域内所有星星的代价即可。

    • 如果要在蓝色区域内保留一颗星星,我们枚举保留哪一颗。当保留某一颗星星时,这颗星星下方的子树会受到限制(可以结合样例2理解)。

      首先,对于照片的每一列,也就是每一个(x)坐标,一定有一个包含它的,且深度最大的节点,我们记这个节点为(p[x])

      发现,如果我们要保留的星星横坐标为(x),则笛卡尔树上,(p[x])到当前节点的这一条链上,每个节点的蓝色区域内的星星都必须全部删除。如下图(黑色节点表示这个节点蓝色区域内的星星被全部删除):

      因此我们对每个节点,维护一个(g[l,r]),表示强制只进行第(1)种转移的代价,和进行第(2)种转移的代价的差。那么(f[l,r])的第二种转移,就相当于只进行第一种转移的代价,减去要保留的这颗星星的(c_i),再加上从([l,r])(p[x])的这条链上的节点的(g)的和。

      求树上一条链的和,可以用树链剖分实现。

    到这里这道题的主要思路基本讲完了。还有一个实现上的小问题,就是怎么把每颗星星,精准定位到笛卡尔树上某个节点的蓝色区域里。我们可以线段树上二分,找到这颗星星左边第一个高度大于等于该星星(y)的楼房,右边第一个高度大于等于该星星(y)的楼房,这两幢楼房之间,一定是笛卡尔树上的一个节点,把该星星放到这个节点的蓝色区域内就好了。

    时间复杂度(O(mlog n+nlog^2n))。分别是线段树上二分和树链剖分的复杂度。

    参考代码

  • 相关阅读:
    SQLSERVER中的sp_reset_connection存储过程的作用
    SQLSERVER数据库经常置疑的原因
    sqlserver2005数据库邮件
    SQLSERVER书签查找的通俗理解
    msdb数据库里的表究竟存储什么信息
    造成阻塞和死锁的3大原因:
    SQLSERVER中的锁资源类型RID KEY PAG EXT TAB DB FIL
    总结一下要影响SQLSERVER锁的申请和释放行为要考虑的因素
    Linux下getsockopt/setsockopt 函数说明
    HTTP协议详解(转)
  • 原文地址:https://www.cnblogs.com/dysyn1314/p/12564296.html
Copyright © 2011-2022 走看看