尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

RMQ与LCA学习笔记

RMQ与LCA学习笔记
📅 发布时间:2026/6/20 12:26:29

在开始之前先提一下RMQ与LCA这两个东西有什么关系
对于一个序列,对它构建出一颗笛卡尔树之后,两个点的LCA就是原序列中这两个点之间的最大值/最小值(取决于建树时的比较方式)
而对于一棵树,求出来他的欧拉序之后,两个点的LCA,就是两个点在欧拉序第一次出现的位置之间的深度最小值的点
所以LCA问题和RMQ问题是可以相互转换的

RMQ

RMQ 即区间最值问题,根据情景的不同,我们可以给出不同的方法

静态区间最值问题

ST表

ST表,是一个处理静态可重复贡献问题的利器,区间最值显然是可以重复贡献的。
记 \(st_{i,k}\) 表示原序列中 \([i,i+2^k-1]\) 中的最值,显然初始化是 \(st_{i,0}=a[i]\)
我们可以将 \([i,i+2^k-1]\) 拆分成 \([i,i+2^{k-1}-1]\) 和 \([i+2^{k-1},i+2^{k}-1]\) ,这两个区间中的最值显然是 \(st_{i,k-1}\) 和 \(st_{i+2^{k-1},k-1}\)
所以我们从小到大枚举 \(k\) ,用 \(st_{i,k-1}\) 和 \(st_{i+2^{k-1},k-1}\) 更新 \(st_{i,k}\)

for(int i=1;i<=n;i++)f[i][0]=read();
int t=log2(n);
for(int i=1;i<=t;i++){for(int k=1;k<=n-(1<<i)+1;k++){f[k][i]=max(f[k][i-1],f[k+(1<<(i-1))][i-1]);}
}//这里的i,k与上文中是反过来的

查询时,需要将 \([l,r]\) 拆成两个区间,使它们覆盖整个 \([l,r]\) ,可以发现 \(st_{l,\lfloor log_{2}{r-l+1}\rfloor}\) \(st_{r-2^{\lfloor log_{2}{r-l+1}\rfloor}+1,\lfloor log_{2}{r-l+1}\rfloor}\) 可以覆盖整个区间。

for(int i=1;i<=m;i++){int l,r;l=read();r=read();int k=log2(r-l+1);write(max(f[l][k],f[r-(1<<k)+1][k]));puts("");
}

预处理时间复杂度为 \(O(nlogn)\) ,单次查询复杂度为 \(O(1)\)

Method of Four Russians

就是人们常说的“四毛子”,这个算法在ST表的基础上进行了优化。
对序列进行分块,设块长为 \(B\) ,在块间建立ST表,时间复杂度为 \(O(\frac{N}{B}log{\frac{N}{B}})\),在块内建立ST表,时间复杂度为 \(O(\frac{N}{B}Blog{B})\).
查询时,若 \(l,r\) 在同一个块内,直接用块内的ST表查询,若 \(l,r\) 不在同一个块内,那么对于散块用块内的ST表查询,对于整块用块间的ST表查询。查询时间复杂度为 \(O(1)\)
当 \(B\) 取 \(O(log_2{n})\) 时,预处理时间复杂度是 \(O(nloglogn)\)

struct FR{int ST[N/len+5][log2(N/len)+5],st[N][log2(len)+5];struct block{int l,r,ma;}b[N/len+5];void init(){for(int i=1;i<=id(n);i++){b[i].l=b[i-1].r+1;b[i].r=i*len;b[i].ma=0;}b[id(n)].r=n;for(int i=1;i<=id(n);i++){int t=log2(b[i].r-b[i].l+1);for(int k=b[i].l;k<=b[i].r;k++)st[k][0]=a[k],b[i].ma=max(b[i].ma,a[k]);for(int k=1;k<=t;k++){for(int j=b[i].l;j+(1<<k)-1<=b[i].r;j++){st[j][k]=max(st[j][k-1],st[j+(1<<(k-1))][k-1]);}				}}for(int i=1;i<=id(n);i++)ST[i][0]=b[i].ma;int t=log2(id(n));for(int i=1;i<=t;i++){for(int k=1;k+(1<<i)-1<=id(n);k++){ST[k][i]=max(ST[k][i-1],ST[k+(1<<(i-1))][i-1]);}}}int ask(int l,int r){int p=id(l),q=id(r);if(p==q){int t=log2(r-l+1);return max(st[l][t],st[r-(1<<t)+1][t]);}int x,y,z;int t=log2(b[p].r-l+1);x=max(st[l][t],st[b[p].r-(1<<t)+1][t]);t=log2(r-b[q].l+1);y=max(st[b[q].l][t],st[r-(1<<t)+1][t]);if(p+1>q-1)return max(x,y);t=log2(q-1-(p+1)+1);z=max(ST[p+1][t],ST[(q-1)-(1<<t)+1][t]);return max(x,max(y,z));}
}f;

但由于每次查询会使用3次ST表,所以常数会比直接建ST表大很多,在 \(n\) 较小的时候还是直接写ST表好

优化

当 \(l,r\) 不在一个块内时,考虑对于散块的查询,我们只需要考虑一个前缀或后缀的贡献就可以了,这样就可以将ST表调用次数降低到1次

O(N)-O(1)Rmq

四毛子的瓶颈在于当 \(l,r\) 在同一块时,没法做到快速处理。
这里给出一个基于状压的线性RMQ的做法
……

相关新闻

  • mamba-硬件感知算法
  • gitee和github如何修改仓库名并且保持与原远程仓库的连接?(手把手教学) - 实践
  • 第十一篇

最新新闻

  • 使用acme.sh获取免费泛域名SSL证书:从DNS验证到自动化部署
  • 2026年6月最新天梭中国官方售后热线服务电话客户地址网点 - 天梭服务中心
  • 2026上海黄金变现去哪靠谱?本地5家正规回收渠道深度拆解,第1家真的全能无短板 - 速递信息
  • 基于ACME协议的SSL证书自动化管理:从原理到实践
  • DeepSeek-V4架构解析:DSA稀疏注意力与MoE路由实战
  • 开源推理模型本地部署实战指南

日新闻

  • 信任的进化:技术实现详解——如何用JavaScript构建博弈论模拟器
  • Terrakube自定义工作流:如何集成OPA、Infracost等工具扩展IaC能力
  • grunt-concurrent快速入门:5分钟学会并行运行Grunt任务

周新闻

  • 3步解锁iOS设备:applera1n激活锁绕过完全指南
  • 39 2026 人工智能证书终极盘点,普通人选 AI 证书可以从这些方向入手
  • Redis 暴露公网有多危险?从端口检查到补救步骤

月新闻

  • 【总结】入门篇:50句话让你记住架构核心概念
  • WeChatMsg技术方案解析:实现Mac微信数据自主管理的完整解决方案
  • WeChatMsg:革新性微信数据备份方案,打造你的专属数字记忆库

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号