




全文预览已结束
下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
RMQ/LCA问题与ST(Sparse Table)算法RMQ(Range Minimum/Maximum Query)问题是求区间最值问题。你当然可以写个O(n)的,但是万一要询问最值1000000遍,估计你就要挂了。这时候你可以放心地写一个线段树(前提是不写错)O(logn)的复杂度应该不会挂。但是,ST算法,它可以做到O(nlogn)的预处理,O(1)地回答每个询问。来看一下ST算法是怎么实现的(以最大值为例): 首先是预处理,用一个DP解决。设ai是要求区间最值的数列,fi, j表示从第i个数起连续2j个数中的最大值。例如数列3 2 4 5 6 8 1 2 9 7 ,f1,0表示第1个数起,长度为20=1的最大值,其实就是3这个数。f1,2=5,f1,3=8,f2,0=2,f2,1=4从这里可以看出fi,0其实就等于ai。这样,Dp的状态、初值都已经有了,剩下的就是状态转移方程。我们把fi,j平均分成两段(因为fi,j一定是偶数个数字),从i到i+2(j-1)-1为一段,i+2(j-1)到i+2j-1为一段(长度都为2(j-1))。用上例说明,当i=1,j=3时就是3,2,4,5 和 6,8,1,2这两段。fi,j就是这两段的最大值中的最大值。于是我们得到了动规方程Fi, j=max(Fi,j-1, Fi + 2(j-1),j-1) 接下来是得出最值,也许你想不到计算出fi,j有什么用处,一般毛想想计算max还是要O(logn),甚至O(n)。但有一个很好的办法,做到了O(1)。还是分开来。如在上例中我们要求区间2,8的最大值,就要把它分成2,5和5,8两个区间,因为这两个区间的最大值我们可以直接由f2,2和f5,2得到。扩展到一般情况,就是把区间L,R分成两个长度为2n的区间(保证有fi,j对应)。直接给出表达式:k := ln(R-L+1) / ln(2);ans := max(FL,k, FR - 2k+1, k);这样就计算了从i开始,长度为2t次的区间和从r-2i+1开始长度为2t的区间的最大值(表达式比较烦琐,细节问题如加1减1需要仔细考虑.另外还有一篇RMQ问题和LCA问题/s/blog_40d4357f010004ug.html最近公共祖先与RMQ问题一、最近公共祖先(Least Common Ancestors)对于有根树T的两个结点u、v,最近公共祖先LCA(T,u,v)表示一个结点x,满足x是u、v的祖先且x的深度尽可能大。另一种理解方式是把T理解为一个无向无环图,而LCA(T,u,v)即u到v的最短路上深度最小的点。这里给出一个LCA的例子:例一对于T=V=1,2,3,4,5E=(1,2),(1,3),(3,4),(3,5)则有:LCA(T,5,2)=1LCA(T,3,4)=3LCA(T,4,5)=3-二、RMQ问题(Range Minimum Query)RMQ问题是指:对于长度为n的数列A,回答若干询问RMQ(A,i,j)(i,j=n),返回数列A中下标在i,j里的最小值下标。这时一个RMQ问题的例子:例二对数列:5,8,1,3,6,4,9,5,7 有:RMQ(2,4)=3RMQ(6,9)=6RMQ问题与LCA问题的关系紧密,可以相互转换,相应的求解算法也有异曲同工之妙。下面给出LCA问题向RMQ问题的转化方法。对树进行深度优先遍历,每当“进入”或回溯到某个结点时,将这个结点的深度存入数组E最后一位。同时记录结点i在数组中第一次出现的位置(事实上就是进入结点i时记录的位置),记做Ri。如果结点Ei的深度记做Di,易见,这时求LCA(T,u,v),就等价于求ERMQ(D,Ru,Rv),(RuRv)。例如,对于第一节的例一,求解步骤如下:数列Ei为:1,2,1,3,4,3,5,3,1Ri为:1,2,4,5,7Di为:0,1,0,1,2,1,2,1,0于是有:LCA(T,5,2) = ERMQ(D,R2,R5) = ERMQ(D,2,7) = E3 = 1LCA(T,3,4) = ERMQ(D,R3,R4) = ERMQ(D,4,5) = E4 = 3LCA(T,4,5) = ERMQ(D,R4,R5) = ERMQ(D,5,7) = E6 = 3易知,转化后得到的数列长度为树的结点数的两倍减一,所以转化后的RMQ问题与LCA问题的规模同次。ST算法举例:POJ 3264 /JudgeOnline/problem?id=3264参见 /Victordu/archive/2008/09/18/50429.htmlconst int size = 50001;int minNumsize16;int maxNumsize16;int main() int n, m; scanf(%d%d, &n, &m); for(int i=1; i=n; i+) int t; scanf(%d, &t); minNumi0 = t; maxNumi0 = t; for(int j=1; j=log(double)n)/log(2.); j+) for(int i=1; i=n; i+) minNumij = minNumij-1; maxNumij = maxNumij-1; if(i + (1(j-1) = n) minNumij = min(minNumij, minNumi + (1(j-1)j-1); maxNumij = max(maxNumij, maxNumi + (1(j-1)j-1); for(int i=0; i right) int t = left; left = right; right = t; int k = floor(log(double)right - left + 1)/log(2.); printf(%dn, max(maxNumleftk, maxNumright - (1k) + 1k) - min(minNumleftk, minNumright - (1k) + 1k); return 0;ST算法求解RMQ问题 RMQ(Range Minimum/Maximum Query)问题是求区间最值问题。可以写一个线段树,但是预处理和查询的复杂度都是O(logn)。这里有更牛的算法,就是ST算法,它可以做到O(nlogn)的预处理,O(1)!地回答每个询问。 来看一下ST算法是怎么实现的(以最大值为例): 首先是预处理,用一个DP解决。设ai是要求区间最值的数列,fi,j表示从第i个数起连续2j个数中的最大值。例如数列3 2 4 5 6 8 1 2 9 7 ,f1,0表示第1个数起,长度为20=1的最大值,其实就是3这个数。f1,2=5,f1,3=8,f2,0=2,f2,1=4从这里可以看出fi,0其实就等于ai。这样,Dp的状态、初值都已经有了,剩下的就是状态转移方程。我们把fi,j平均分成两段(因为fi,j一定是偶数个数字),从i到i+2(j-1)-1为一段,i+2(j-1)到i+2j-1为一段(长度都为2(j-1))。用上例说明,当i=1,j=3时就是3,2,4,5 和 6,8,1,2这两段。fi,j就是这两段的最大值中的最大值。于是我们得到了动规方程Fi,j=max(Fi,j-1,Fi+2(j-i),j-1). 接下来是得出最值,也许你想不到计算出fi,j有什么用处,一般毛想想计算max还是要O(logn),甚至O(n)。但有一个很好的办法,做到了O(1)。还是分开来。如在上例中我们要求区间2,8的最大值,就要把它分成2,5和5,8两个区间,因为这两个区间的最大值我们可以直接由f2,2和f5,2得到。扩展到一般情况,就是把区间l,r分成两个长度为2n的区间(保证有fi,j对应)。直接给出表达式:fi,j 表示 从第 i 个数数 2j 中最小的数那么:最大值 fi,j=max(fi,j-1,fi+2(j-1),j-1); 最小值 fi,j=min(fi,j-1,fi+2(j-1),j-1);模板: #include#include#definemax(a,b)(a)(b)?(a):(b)#definemin(a,b)(a)(b)?(a):(b)usingnamespacestd;constintmaxn=50001;inthmaxn;intmxmaxn16,mnmaxn16;intn,q;voidrmq_init()inti,j;for(j=1;j=n;j+)mxj0=mnj0=hj;intm=floor(log(double)n)/log(2.0);for(i=1;i0;j-)mxji=mxji-1;if(j+(1(i-1)=n)mxji=max(mxji,mxj+(1(i-1)i-1);for(i=1;i0;j-)mnji=mnji-1;if(j+(1(i-1)=n)mnji=min(mnji,mnj+(1(i-1)i-1);intrmq(intl,intr)intm=floor(log(double)(r-l+1)/
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 护理专业知识更新试题及答案
- 大米安全生产培训课件
- 2025年休闲鞋鞋底项目可行性研究报告
- 毕节市事业单位2025年面向社会公开招聘笔试联考发布笔试历年典型考题及考点剖析附带答案详解
- 深入理解2025年卫生资格考试试题与答案
- 2025聘用外国专业人士合同范本
- 韶关2025年韶关市在选调生招录中同步开展事业单位人员招聘笔试历年参考题库附带答案详解
- 行政管理经济法的核心问题试题及答案
- 行政法学中的条款解读试题及答案
- 行政管理备考中的实战策略:试题及答案
- 2025广东二模语文(含答案)
- 消渴肾病的中医护理方案
- 《高压输电线路巡检维护合同》
- 《中国古典文学中的咏鱼诗与生态文化》论文
- 商品混凝土管理制度
- 轻钢龙骨隔墙施工方案
- 2025年浙江温州市公用事业发展集团有限公司招聘笔试参考题库附带答案详解
- 2025年天津市武清区国资产经营投资限公司面向社会公开选聘工作人员高频重点模拟试卷提升(共500题附带答案详解)
- 业主大会申请书
- 2025年八人合伙企业股权分配协议书
- (部编版)语文五年级上册“小古文”阅读理解训练82篇附参考答案
评论
0/150
提交评论