PS:

介绍:http://blog.csdn.net/liang5630/article/details/7917702

RMQ算法。是一个高速求区间最值的离线算法,预处理时间复杂度O(n*log(n))。查询O(1)。所以是一个非常高速的算法,当然这个问题用线段树相同可以解决。

1、求区间的最大值和最小值!

代码例如以下:

#include <cstdio>
#include <cstring>
#include <cmath>
#include <iostream>
using namespace std;
const int MAXN = 100117;
int n,query;
int num[MAXN]; int F_Min[MAXN][20],F_Max[MAXN][20]; void Init()
{
for(int i = 1; i <= n; i++)
{
F_Min[i][0] = F_Max[i][0] = num[i];
} for(int i = 1; (1<<i) <= n; i++) //按区间长度递增顺序递推
{
for(int j = 1; j+(1<<i)-1 <= n; j++) //区间起点
{
F_Max[j][i] = max(F_Max[j][i-1],F_Max[j+(1<<(i-1))][i-1]);
F_Min[j][i] = min(F_Min[j][i-1],F_Min[j+(1<<(i-1))][i-1]);
}
}
} int Query_max(int l,int r)
{
int k = (int)(log(double(r-l+1))/log((double)2));
return max(F_Max[l][k], F_Max[r-(1<<k)+1][k]);
} int Query_min(int l,int r)
{
int k = (int)(log(double(r-l+1))/log((double)2));
return min(F_Min[l][k], F_Min[r-(1<<k)+1][k]);
} int main()
{
int a,b;
scanf("%d %d",&n,&query);
for(int i = 1; i <= n; i++)
scanf("%d",&num[i]);
Init();
while(query--)
{
scanf("%d %d",&a,&b);
printf("区间%d到%d的最大值为:%d\n",a,b,Query_max(a,b));
printf("区间%d到%d的最小值为:%d\n",a,b,Query_min(a,b));
printf("区间%d到%d的最大值和最小值仅仅差为:%d\n",a,b,Query_max(a,b)-Query_min(a,b));
}
return 0;
}

2、求区间内出现次数最多的数字出现的次数。

代码例如以下:

#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std; const int maxn = 100017;
int num[maxn], f[maxn], MAX[maxn][20];
int n;
int max(int a,int b)
{
return a>b ? a:b;
}
int rmq_max(int l,int r)
{
if(l > r)
return 0;
int k = log((double)(r-l+1))/log(2.0);
return max(MAX[l][k],MAX[r-(1<<k)+1][k]);
}
void init()
{
for(int i = 1; i <= n; i++)
{
MAX[i][0] = f[i];
}
int k = log((double)(n+1))/log(2.0);
for(int i = 1; i <= k; i++)
{
for(int j = 1; j+(1<<i)-1 <= n; j++)
{
MAX[j][i] = max(MAX[j][i-1],MAX[j+(1<<(i-1))][i-1]);
}
}
}
int main()
{
int a, b, q;
while(scanf("%d",&n) && n)
{
scanf("%d",&q);
for(int i = 1; i <= n; i++)
{
scanf("%d",&num[i]);
}
sort(num+1,num+n+1);
for(int i = 1; i <= n; i++)
{
if(i == 1)
{
f[i] = 1;
continue;
}
if(num[i] == num[i-1])
{
f[i] = f[i-1]+1;
}
else
{
f[i] = 1;
} } init(); for(int i = 1; i <= q; i++)
{
scanf("%d%d",&a,&b);
int t = a;
while(t<=b && num[t]==num[t-1])
{
t++;
}
int cnt = rmq_max(t,b);
int ans = max(t-a,cnt);
printf("%d\n",ans);
}
}
return 0;
}
/*
10 3
-1 -1 1 2 1 1 1 10 10 10
2 3
1 10
5 10
*/

版权声明:本文博客原创文章。博客,未经同意,不得转载。

RMQ(模板 ST 区间最值,频繁的间隔时间)的更多相关文章

  1. POJ - 3264 Balanced Lineup (RMQ问题求区间最值)

    RMQ (Range Minimum/Maximum Query)问题是指:对于长度为n的数列A,回答若干询问RMQ(A,i,j)(i,j<=n),返回数列A中下标在i,j里的最小(大)值,也就 ...

  2. RMQ(求区间最值问题)

    学习博客:https://blog.csdn.net/qq_31759205/article/details/75008659 RMQ(Range Minimum/Maximum Query),即区间 ...

  3. 【模板】RMQ(计算区间最值)

    ①一维RMQ (1) dp[i,j] 表示从第i个数起连续2j个数中的(最大值min.最小值max.最大公约数gcd……),通过更改下列代码中的红色函数即可实现. (2) b数组放置所需查询的数列. ...

  4. hdu3183 rmq求区间最值的下标

    两个月前做的题,以后可以看看,是rmq关于求区间最值的下标 /* hdu3183 终点 给一个整数,可以删除m位,留下的数字形成一个新的整数 rmq 取n-m个数,使形成的数最小 */ #includ ...

  5. RMQ的st表算法

    此算法可用来处理区间最值问题,预处理时间为O(nlogn),查询时间为O(1) 此算法主要基于倍增思想,用以数组st[i][j]表示从第i个元素开始向后搜2的j次方的最值 可用递推的方式求得:st[i ...

  6. ST表 求 RMQ(区间最值)

    RMQ即Range Minimum/Maximun Query,中文意思:查询一个区间的最小值/最大值 比如有这样一个数组:A{3 2 4 5 6 8 1 2 9 7},然后问你若干问题: 数组A下标 ...

  7. 【RMQ】 区间最值查询详解

    1. 概述 RMQ(Range Minimum/Maximum Query),即区间最值查询,是指这样一个问题:对于长度为n的数列A,回答若干询问RMQ(A,i,j)(i,j<=n),返回数列A ...

  8. RMQ之ST算法模板

    #include<stdio.h> #include<string.h> #include<iostream> using namespace std; ; ],M ...

  9. 模板 RMQ问题ST表实现/单调队列

    RMQ (Range Minimum/Maximum Query)问题是指: 对于长度为n的数列A,回答若干询问RMQ(A,i,j)(i,j<=n),返回数列A中下标在i,j里的最小(大)值,R ...

随机推荐

  1. C# 6.0 (C# vNext) 的新功能:Expression Bodied Functions and Properties

    Expression Bodied Function 它可以用在: methods user-defined operators type conversions read-only properti ...

  2. HDU 1420 Prepared for New Acmer【中国剩余定理】

    /* 解决问题的思路:中国剩余定理,还要注意的是数据的类型,要使用__int64位 解决人:lingnichong 解决时间:2014-08-30 06:56:35 :简单题 */ Prepared ...

  3. Java执行批处理.bat文件(有问题???求高手帮忙解答!!!)

                           Java执行批处理.bat文件(有问题???求高手帮忙解答!!!) 在项目开发中常常都会遇到需要在代码中调用批处理bat脚本,把自己在项目中遇到过的总结下 ...

  4. PL/SQL 游标的使用

     游标的使用 ①游标概念 为了处理SQL 语句,ORACLE 必须分配一片叫上下文( context area )的区域来处理所必需的信息, 当中包含要处理的行的数目.一个指向语句被分析以后的表示 ...

  5. [Android]Can&#39;t create handler inside thread that has not called Looper.prepare()

    更新是由于在新的线程来打开UI只有一个错误.子线程更新主线程UI需要使用Handler. 还有比如今天出现以下错误.码,如以下: send.setOnClickListener(new OnClick ...

  6. STL内存分配

    STL内存创建 Owed by: 春夜喜雨 http://blog.csdn.net/chunyexiyu  转载请标明来源 1.      Stl内存创建基类模板__malloc_alloc_tem ...

  7. nyoj 题号12 水厂(两)——南阳oj

    标题信息: 喷水装置(二) 时间限制:3000 ms  |  内存限制:65535 KB 难度:4 描写叙述 有一块草坪.横向长w,纵向长为h,在它的橫向中心线上不同位置处装有n(n<=1000 ...

  8. Webx框架:Valve详细解释

    Valve请求,用于控制过程的操作.它采用责任设计模式链(类别似至struts拦截器).valve阀装置,阀控制水流量(网络请求)趋势. 他们阀门定义. public class MyValve im ...

  9. IIS URL Rewrite Module防盗链规则配置方法

    IIS版本:IIS 7.5 URL Rewrite组件:IIS URL Rewrite Module(http://www.iis.net/downloads/microsoft/url-rewrit ...

  10. IOS开发——手动设置屏幕旋转

    在移动开发过程.您可能需要跨越看看你的手机.有可能是所有的接口必须跨越,有可能是一个交叉通过电话,当用户当,你的接口也希望他能跨越.还有可能的是,界面的一部分需要被侧向显示.视情况而定,有不同的方法来 ...