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

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

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

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

静态问题至此已经解决。

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

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

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

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

代码

posted @ 2023-09-13 17:17  寂静的海底  阅读(7)  评论(0编辑  收藏  举报  来源