首先讲一下RMQ算法的意思。

RMQ(Range Minimum Query,RMQ)范围最小值,给出一个n个元素的数组,计算min(A[L],A[L+1],...,A[R-1],A[R]);

这里运用了dp,先构建d[i][j]表示第i位开始2^j个元素中最小的值;

转移方程d[i][j]=min(d[i][j-1],d[i+2^(j-1)][j-1]);

建议画一张图来体验一下这个的意思。

实现:

 void RMQ_init(int n)
{
for(int i=;i<=n;i++) d[i][]=s1[i];
for(int j=;(<<j)<=n;j++){
for(int i=;i+(<<(j-))<=n;i++){
d[i][j]=max(d[i][j-],d[i+(<<(j-))][j-]);
}
}
}

在查找的时候找到(1<<j)<=(R-L+1)的j的最大值,也就是说2^j<=(R-L+1)同时还有2^(j-1)>=(R-L+1)/2;

从L开始往右找2^(j-1)个元素的最小值,即d[L][j-1];

以R结尾的连续的2^(j-1)个元素的最小值,即d[R-(1<<(j-1))+1][j-1];

再求以上两值的最小值,呃呃,就算出来了。中间重叠计算的元素不影响最后结果。

实现:

 int RMQ(int L,int R)
{
int k=;
while((<<(k+)) <= R-L+) k++;
return max(d[L][k],d[R-(<<k)+][k]);
}

这样就开心地学会了RMQ~~

现在开始实战

先把题目给出的非降序序列变成计数的形式,比如-1 -1 1 1 1 1 3 10 10 10,变成2 4 1 3;

因为题目不是直接问你第几段到第几段,而是给你两个下标L,R,要你求最大值,所以你要记录一下每个下标对应的段的下标。

比如以上的序列就要变成1 1 2 2 2 2 3 4 4 4;

然后由于题目问你的时候,给你的下标不会恰好就是左边段的起始点和右边段的结束点;

所以,要把一个询问拆成三小块:

1.L到L对应段的最右有多少元素;

2.R到R对应段的最左有多少元素;

3.L对应段右边第一个段,和R对应段左边第一个段,之间最大为多少。

那么只要把RMQ的求最小值变为求最大值就可以求出来了。

实现:

 #include <stdio.h>
const int maxn=; int s[maxn],s1[maxn];
int d[maxn][];
int num[maxn],left[maxn],right[maxn]; int max(int x,int y)
{
return (x>y)?x:y;
} void RMQ_init(int n)
{
for(int i=;i<=n;i++) d[i][]=s1[i];
for(int j=;(<<j)<=n;j++){
for(int i=;i+(<<(j-))<=n;i++){
d[i][j]=max(d[i][j-],d[i+(<<(j-))][j-]);
}
}
} int RMQ(int L,int R)
{
int k=;
while((<<(k+)) <= R-L+) k++;
return max(d[L][k],d[R-(<<k)+][k]);
} int main()
{
int n,q,rear,L,R,ans;
while(~scanf("%d %d",&n,&q)&&n){
rear=;
for(int i=;i<=n;i++){
scanf("%d",&s[i]);
if(s[i]!=s[i-]){
s1[++rear]=;
left[rear]=i;
}
else s1[rear]++;
right[rear]=i;
num[i]=rear;
}
RMQ_init(rear);
while(q--){
scanf("%d %d",&L,&R);
if(num[L]==num[R]) ans=R-L+;
else if(num[L]+==num[R]){
ans=max(right[num[L]]-L+,R-left[num[R]]+);
}else{
ans=max(right[num[L]]-L+,R-left[num[R]]+);
ans=max(ans,RMQ(num[right[num[L]]+],num[left[num[R]]-]));
}
printf("%d\n",ans);
}
}
return ;
}

对于其中L和R是同一个段,和L和R是相邻的段的情况要分开讨论,容易实现。

thx

UVa 11235 RMQ的更多相关文章

  1. UVa 11235 (RMQ) Frequent values

    范围最值问题,O(nlogn)的预处理,O(1)的查询. 这个题就是先对这些数列进行游程编码,重复的元素只记录下重复的次数. 对于所查询的[L, R]如果它完全覆盖了某些连续的重复片段,那么查询的就是 ...

  2. UVA 11235 (RMQ) 频繁出现的数值

    题目大意是给出一个非降序排列的数组,然后n个询问,每次询问一个区间内出现次数最多的数的次数. 首先要弄清楚题目的是一个非降序的数组,那么说明相等的数都会在一起,类似于11223334569这样的,那么 ...

  3. Uva 11235 RMQ问题

    RMQ: 有一个不变的数组,不停的求一个区间的最小值. 使用倍增的思想优化到logN; d(i,j) 表示从 i 开始的,长度为2j的一段元素中的最小值. 那么状态转移方程: d(i,j) = min ...

  4. uva 11235 RMQ范围最大值

    题目大意:给一个整数上升序列,对于一系列询问区间(i,j),回答这段区间出现次数最多值所出现的次数. 分析:一个上升序列,相同的值聚集在一起,把相同的值的区间看作一个整体,假设这样的整体有n个,把他们 ...

  5. UVA 11235 RMQ算法

    上次的湘潭赛的C题,用线段树敲了下还是WA,不知道为何,我已经注意了处理相同数据,然后他们当时用的RMQ. 所以学了下RMQ,感觉算法思想是一样的,RMQ用了DP或者是递推,由单个数到2^k往上推,虽 ...

  6. UVA 11235 Frequent values 线段树/RMQ

    vjudge 上题目链接:UVA 11235 *******************************************************大白书上解释**************** ...

  7. RMQ算法 以及UVA 11235 Frequent Values(RMQ)

    RMQ算法 简单来说,RMQ算法是给定一组数据,求取区间[l,r]内的最大或最小值. 例如一组任意数据 5 6 8 1 3 11 45 78 59 66 4,求取区间(1,8)  内的最大值.数据量小 ...

  8. UVA 11235 (游程编码+ST算法)

    题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=23846 题目大意:给定一个升序序列,有q次询问,每次询问(L,R) ...

  9. UVa 12299 RMQ with Shifts(移位RMQ)

    p.MsoNormal { margin: 0pt; margin-bottom: .0001pt; text-align: justify; font-family: "Times New ...

随机推荐

  1. java 输入年月,获取日历表

    /* 做日历作业: 输入一个时间如: 2016-11 就显示2016年11月的日历显示 */ import java.util.*; class calendar { public static vo ...

  2. PHP的开发环境

    快速搭建工作环境,测试环境,开始PHP的编程之旅. liunx CentOS 6.4安装配置LAMP服务器(Apache+PHP5+MySQL) 准备篇: 1.配置防火墙,开启80端口.3306端口v ...

  3. js实现两个页面之间跳转参数传递

    html在设计时,规定跳转地址后加"?"表示从此开始为跟随页面地址跳转的参数. 有时候,我们希望获得相应的跳转前页面里的内容,这时候我们就可以考虑将内容以参数形式放到地址中传过来, ...

  4. Android-简单拨号器案例

    Android [19]简单电话拨号器 @方法步骤 1.新建一个android程序,项目名设置为 phone  ,然后打开  phone->res->layout->activity ...

  5. 第九周 psp

    团队项目PSP 一:表格     C类型 C内容 S开始时间 E结束时间 I时间间隔 T净时间(mins) 预计花费时间(mins) 讨论 讨论用户界面 9:50 12:45 35 45 80 分析与 ...

  6. 八月25日认识java

    java的起源:1991年SUN公司启动的“Green”项目制作出的Star7, java的发展:于1995年5月23日正NSU式发布第一个java开发工具:java在1998年推出JDK1.2,表示 ...

  7. 解决svn working copy locked问题

    标题:working copy locked 提示:your working copy appears to be locked. run cleanup to amend the situation ...

  8. 20145220&20145209&20145309信息安全系统设计基础实验报告(5)

    20145220&20145209&20145309信息安全系统设计基础实验报告(5) 实验报告链接: http://www.cnblogs.com/zym0728/p/6132249 ...

  9. 数据结构与算法分析——C语言描述 第三章的单链表

    数据结构与算法分析--C语言描述 第三章的单链表 很基础的东西.走一遍流程.有人说学编程最简单最笨的方法就是把书上的代码敲一遍.这个我是头文件是照抄的..c源文件自己实现. list.h typede ...

  10. iOS缓存功能

    之前做缓存,没有考虑过这个具体的实现. 移动应用在处理网络资源时,一般都会做离线缓存处理,其中以图片缓存最为典型,其中很流行的离线缓存框架为SDWebImage. 但是,离线缓存会占用手机存储空间,所 ...