实现RMQ的两种常用方法
RMQ
RMQ(Range Maximum/Minimum Question)是指区间最值问题,在OI中较为常见,一般可以用ST表和线段树实现。
ST表是基于倍增思想的一种打表方法,在确定区间范围和所有的值后利用倍增预处理出$2^k$长度的区间内的最值,然后$O(1)$查询。优点是查询快且操作简便,缺点是不能进行动态操作,只支持静态查询。
Code:(POJ模板题)
//It is made by HolseLee on 23rd July 2018
//POJ 3264
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<iostream>
#include<iomanip>
using namespace std;
const int N=5e4+;
int n,m,a[N];
int mx[N][],mi[N][];
inline int read()
{
char ch=getchar();int num=;bool flag=false;
while(ch<''||ch>''){if(ch=='-')flag=true;ch=getchar();}
while(ch>=''&&ch<=''){num=num*+ch-'';ch=getchar();}
return flag?-num:num;
}
void ready()
{
for(int j=;j<=;j++)
for(int i=;i<=n;i++)
if(i+(<<(j-))<=n){
mx[i][j]=max(mx[i][j-],mx[i+(<<(j-))][j-]);
mi[i][j]=min(mi[i][j-],mi[i+(<<(j-))][j-]);}
}
inline int quary(int l,int r)
{
int maxx=-,minn=;
int k=(int)(log((double)(r-l+))/log(2.0));
maxx=max(mx[l][k],mx[r-(<<k)+][k]);
minn=min(mi[l][k],mi[r-(<<k)+][k]);
return maxx-minn;
}
int main()
{
n=read();m=read();
memset(mx,-,sizeof(mx));
memset(mi,0x7f,sizeof(mi));
for(int i=;i<=n;i++){
a[i]=read();
mi[i][]=mx[i][]=a[i];}
ready();int x,y;
for(int i=;i<=m;i++){
x=read();y=read();
printf("%d\n",quary(x,y));}
return ;
}
线段树就不用多说了,除了可以同时维护最大和最小值意外,还能维护更多信息,操作同样也方便,而且还支持动态操作。
Code:
//It is made by HolseLee on 23rd July 2018
//POJ 3264
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<iostream>
#include<iomanip>
using namespace std;
const int N=5e4+;
int n,m,a[N];
struct Node{
int mx,mi;
Node(int xx=,int yy=)
{mx=xx;mi=yy;}
}seg[N<<];
inline int read()
{
char ch=getchar();int num=;bool flag=false;
while(ch<''||ch>''){if(ch=='-')flag=true;ch=getchar();}
while(ch>=''&&ch<=''){num=num*+ch-'';ch=getchar();}
return flag?-num:num;
}
inline void update(int rt)
{
seg[rt].mx=max(seg[rt<<].mx,seg[rt<<|].mx);
seg[rt].mi=min(seg[rt<<].mi,seg[rt<<|].mi);
}
inline void build(int l,int r,int rt)
{
if(l>r)return;
if(l==r){
seg[rt].mx=seg[rt].mi=a[l];return;}
int mid=(l+r)>>;
build(l,mid,rt<<);build(mid+,r,rt<<|);
update(rt);
}
inline Node quary(int l,int r,int rt,int L,int R)
{
Node ret(-,);
if(l>R||r<L)return ret;
if(L<=l&&r<=R){return seg[rt];}
int mid=(l+r)>>;
Node lc(-,);
Node rc(-,);
if(L<=mid)lc=quary(l,mid,rt<<,L,R);
if(R>mid)rc=quary(mid+,r,rt<<|,L,R);
ret.mx=max(lc.mx,rc.mx);
ret.mi=min(lc.mi,rc.mi);
return ret;
}
inline int get(int x,int y)
{
int maxx=quary(,n,,x,y).mx;
int minn=quary(,n,,x,y).mi;
return maxx-minn;
}
int main()
{
n=read();m=read();
for(int i=;i<=n;i++)
a[i]=read();
build(,n,);int x,y;
for(int i=;i<=m;i++){
x=read();y=read();
printf("%d\n",get(x,y));}
return ;
}
实现RMQ的两种常用方法的更多相关文章
- jQuery验证元素是否为空的两种常用方法
这篇文章主要介绍了jQuery验证元素是否为空的两种常用方法,实例分析了两种常用的判断为空技巧,非常具有实用价值,需要的朋友可以参考下 本文实例讲述了jQuery验证元素是否为空的两种常用方法.分享给 ...
- 在Quartus II中分配管脚的两种常用方法
在Quartus II中分配管脚的两种常用方法 示范程序 seg7_test.v 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 /* * ...
- vue——props的两种常用方法
vue--props的两种常用方法 1.实现父-->子的通信 举例如下: 父组件 parent.vue <children :channel="object1"> ...
- C#程序实现软件开机自动启动的两种常用方法
C#/WPF/WinForm/.NET程序代码实现软件程序开机自动启动的两种常用方法函数的示例与实例带详细注释 方法一:将软件的快捷方式创建到计算机的自动启动目录下(不需要管理员权限) 1.必要引用 ...
- C#/WPF/WinForm/.NET程序代码实现软件程序开机自动启动的两种常用方法的示例与源码下载带详细注释-源码代码-注册表方式-启动目录快捷方式
C#/WPF/WinForm/.NET程序代码实现软件程序开机自动启动的两种常用方法的示例与源码下载带详细注释-源码代码-注册表方式-启动目录快捷方式 C#实现自动启动的方法-两种方法 源码下载地址: ...
- Struts2中validate数据校验的两种常用方法
本文主要介绍Struts2中validate数据校验的两种方法及Struts2常用校验器. 1.Action中的validate()方法 Struts2提供了一个Validateable接口,这个接 ...
- Android 高级UI设计笔记23:Android 夜间模式之 两种常用方法(降低屏幕亮度+替换theme)
1. 夜间模式 所谓的夜间模式,就是能够根据不同的设定,呈现不同风格的界面给用户,而且晚上看着不伤眼睛.特别是一些新闻类App实现夜间模式是非常人性化的,增强用户体验. 2. 我根据网上的资料 以及自 ...
- html文本溢出显示省略字符的两种常用方法
方法一:使用CSS溢出省略的方式解决 解决效果如下: css代码: display: -webkit-box; display: -moz-box; white-space: pre-wrap; wo ...
- Java连接oracle数据库的两种常用方法
1. 使用thin连接 由于thin驱动都是纯Java代码,并且使用TCP/IP技术通过java的Socket连接上Oracle数据库,所以thin驱动是与平台无关的,你无需安装Oracle客户端,只 ...
随机推荐
- HTML5增强的表单
form元素a.用来定义一个表单,是建立表单的基础元素(就类似定义表格的table)b.表单的其他元素包含在form元素中,其主要子元素有:input/button/select......form元 ...
- poi复杂excel的实现
一:前言 最近帮一个朋友做excel的导出功能,对于我来说还是挺头疼,我看了下表格样式,对于我来说还是挺头疼的,想当年耗子刚刚出社会的时候做的第一份工作,第一份任务就是把把word转换为html,在这 ...
- 2017北京国庆刷题Day3 afternoon
期望得分:100+0+30=130 实际得分:100+36.5+0=136.5 T3 一个变量写混了,丢了30.. 模拟栈 #include<cstdio> #include<cst ...
- 今日文摘:浅谈 HTML5 的游戏化之路
如今商业网站中用于广泛的HTML5无限下拉效果已经越来越受到游戏网站的喜爱.各个品牌为了打造专属自己的游戏特色,纷纷推出了模拟HTML5效果的品牌 站,且都起到了相当好的效果.可是从很多方面来说我们对 ...
- 【CodeForces】913 D. Too Easy Problems
[题目]D. Too Easy Problems [题意]给定n个问题和总时限T,每个问题给定时间ti和限制ai,当解决的问题数k<=ai时问题有效,求在时限T内选择一些问题解决的最大有效问题数 ...
- Web攻防系列教程之 Cookie注入攻防实战
摘要:随着网络安全技术的发展,SQL注入作为一种很流行的攻击方式被越来越多的人所知晓.很多网站也都对SQL注入做了防护,许多网站管理员的做法就是添加一个防注入程序.这时我们用常规的手段去探测网站的SQ ...
- 利用Jsoup模拟跳过登录爬虫获取数据
今天在学习爬虫的时候想着学习一下利用jsoup模拟登录.下面分为有验证码和无验证码的情况进行讨论. ---------------------------无验证码的情况---------------- ...
- Arm-kernel 内存收集【转】
转自:http://blog.csdn.net/linyt/article/details/6627664 Linux kernel的内存管理子系统非常复杂,为了深入了解内存管理系统,我打算分多篇文章 ...
- 64_t1
TOPCOM-0.17.8-2.fc26.x86_64.rpm 13-Feb-2017 22:09 269054 TOPCOM-devel-0.17.8-2.fc26.i686.rpm 13-Feb- ...
- JS时间转换的一个坑位
在做项目的时候,无意发现了一个小东西. new Date('2018-05-15') new Date('2018-5-15') 输出的结果是不同的,相差了8小时.然后让我回忆到之前看的一个时间转换函 ...