【随笔浅谈】颜色段均摊算法

 


十分浅显,由很多内容没有提到。有空再来填坑!

std::set 维护颜色段

定义颜色段(广义):放在一起具有某一性质的一段区间。

构造

可以考虑用一个结构体来表示一个颜色段,一个结构体记录了该颜色段的左右端点,以及该颜色段的某信息。然后将这些结构体放入 std::set 中,std::set 内部按照区间的相对顺序排序。

下文的介绍,以维护具有相同颜色的一段区间为例。

split 分裂

有时候,对于一个颜色段,我们只需要访问它的其中一段信息即可。

这时候就需要分裂该颜色段了。

定义 split(x) 函数:将 x 所在的颜色段 [l,r],分裂成颜色段 [l,x1] 与颜色段 [x,r];并返回颜色段 [x,r]std::set 中的位置。

区间操作

有时候,对于一个序列,我们需要访问一个区间 [l,r] 的信息。

根据分裂操作,就相当于是访问区间 [split(l),split(r+1)) 中颜色段的信息,依次统计即可。

基于数据随机、区间推平 - 颜色段均摊算法

当一道题目同时保证「数据随机」、「具有区间推平操作」时,大量的区间推平会使得整个序列的势能一直维持在较小的范围内。

可以证明运用 std::set 维护颜色段的方法的时间复杂度为 O(nloglogn)hqztrue 的证明

例题选讲

1.【CF 896C】Willem, Chtholly and Seniorious

CF 896C

Description

给出一个长度为 n 的序列 a,你需要维护这个序列,共 m 次操作,共 4 种操作:

  • 1 l r x:对 i[l,r],令 aiai+x
  • 2 l r x:对 i[l,r],令 aix
  • 3 l r x:求区间 [l,r] 内的第 k 小,数字相同算多次。
  • 4 l r x y:求区间 [l,r] 内每个数字的 x 次方模 y 的值。

数据范围:1n,m1051x,y109
时空限制:2000 ms/250 MiB

Solution

该算法起源题。

  • 操作 1:将区间 [l,r] 里所有颜色段的颜色加上 c 即可。
  • 操作 2:将区间 [l,r] 里所有颜色段的颜色赋为 c 即可。
  • 操作 3:访问区间 [l,r] 里的所有颜色段,提取出后排序,找到第一个前缀和 k 的颜色即可。
  • 操作 4:访问区间 [l,r] 里的所有颜色段,将每个颜色段用快速幂统一统计即可。

基于操作影响势能 or 与势能无关 - 颜色段均摊算法

当一道题目保证「操作影响势能」或「操作与势能无关」时,则时间复杂度可以运用均摊分析法来测算。

例题选讲

1.【Luogu P2824】「HEOI2016/TJOI2016」排序

Luogu P2824

Description

给出一个 1n 的排列,现在对这个排列序列进行 m 次局部排序,排序分为两种:

  • 0 l r:表示将区间 [l,r] 的数升序排序。

  • 1 l r:表示将区间 [l,r] 的数降序排序。

最后询问第 q 位置上的数字。

数据范围:1n105
时空限制:4000 ms/256 MiB

Solution

注意到给区间 [l,r] 内的点 升序 / 降序 排序,是赋予了一个区间有序的性质。

可以用权值线段树来维护一个有序区间内的权值信息,然后将这些有序的区间放入 std::set 中。

套用上述模板即可,不同点只是在于对权值线段树的处理:

  • 对于 split 操作,线段树分裂即可;
  • 对于区间排序,线段树合并即可;
  • 对于查询操作,线段树上二分即可。

由于一次排序操作至多会进行两次线段树分裂,增加的点数是 O(logn) 的,故在整个过程中线段树的总节点个数为 O((n+m)logn) 级别的。

在区间排序中,由于每访问一个颜色段,就会将该颜色段删去,使得势能降低。

故总时间复杂度为 O((n+m)logn)

该做法支持多测 + 强制在线。

posted @   Calculatelove  阅读(1435)  评论(3编辑  收藏  举报
编辑推荐:
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· 写一个简单的SQL生成工具
· Manus的开源复刻OpenManus初探
点击右上角即可分享
微信分享提示