像潮落潮涌,送我奔向自由。|

寂静的海底

园龄:3年2个月粉丝:59关注:15

【题解】P5068 数据结构 势能分析 目标寻找

第二次场切 Ynoi,虽然是简单题但还是留念。

考虑我们求的答案,让值为 i 的次数为 di,那么我们要对于 di 求区间和。

考虑怎么查询单个 di,即查询最小的 k 使得 [k(i1)+1,ki] 中没有值,注意到对于 i[1,n] 可能存在的这样的 k 只有调和级数 1i=O(nlogn) 的,然后查询这些段里有没有值,这样就可以求出了所有的 d,进行区间加。

静态问题至此已经解决。

考虑动态问题,加入一个新值的时候,我们要将包含它的所有线段删除,然后对 di 进行修改并维护区间和,拿指针维护 di,移动总量是 O(nlogn) 的,现在问题就是如何找到这些线段。

一个简单的办法是离线,对每个位置记录下覆盖的时间,然后查询区间内最小值就是第一个出现的时间。但是我并没有想到,难过。

考虑拿数据结构找到所有这样的线段,拿树套树做二维偏序的话单次是两只 log 的,总复杂度会有三只 log,不太行。

重新考虑线段和点的关系,把所有线段挂在 l 上,然后对于所有 l 相同的线段,被删除的 r 是一个后缀,维护 n 个指针,删除后暴力后移,现在对于每个位置需要改变 [1,p] 的一个区间中所有 rp 的值,所以考虑拿一个 SegmentTree-Beats 进行维护,在线段树上记录删除区间里面可以删除至少一条线段的最小的 p,然后每次直接在线段树上找可能改变的段,如果目前 p 不能改变最小的 r,就退出,这样每次改变的复杂度是均摊 log,复杂度就是 O(nlog2n) 的,可以在线。

代码

posted @   寂静的海底  阅读(15)  评论(0编辑  收藏  举报  
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起