实现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客户端,只 ...
随机推荐
- 前端PHP入门-030-文件函数API
bool file_exists ( $指定文件名或者文件路径) 功能:文件是否存在. bool is_readable ( $指定文件名或者文件路径) 功能:文件是否可读 bool is_write ...
- thinkphp 5 where 组合条件map数组or
if($inviterId>0) { $arr = Db::table("tablename")-> where("pid=$inviterId") ...
- atcoder #082 E 暴力 计算几何
给出点集,然后求一个凸包的所有的子凸包的贡献总和,贡献计算是凸包内部含边界上点的数量N,凸包的不包含边界的顶点数S,贡献为$2^{N-S}$ 首先很容易想到,凸包上包含内部的所有点构成的子凸包有Sum ...
- eclipse中修改svn用户名和密码
开发中有时候用公共的电脑提交一些代码,eclipse没有专门的切换svn账户的功能.查阅资料得出解决办法: 1. 查看你的Eclipse 中使用的是什么SVN Interface windows & ...
- Prufer Code
1069. Prufer Code Time limit: 0.25 secondMemory limit: 8 MB A tree (i.e. a connected graph without c ...
- java学习——equals()和==的比较
equals 方法是 java.lang.Object 类的方法. 下面从两个方面来说明equals()和==的差别:(1)对于字符串变量来说,使用“==”和“equals()”方法比较字符串时,其比 ...
- 周末发福利了!26个免费的HTML5模版
本期文章我们为大家搜集了很多专业且高质量的HTML5模版,而且还是免费的呦.如果你对编码很熟悉,那么从这些网站里你可以学到很多新技能.来这些国际范的案例中挑选您喜欢的模版学习起来吧:) Zeences ...
- Lua的各种资源2
Lua Directory This page is a top level directory of all Lua content at this wiki, grouped by top ...
- Redhat 7 之 Mariadb(mysql)
Redhat7 之后mysql 改为Mariadba,由于mysql 被卖给了IBM, 有闭源的风险. 所以就另外开了一个新的分支,继续开源.Maria 来源于mysql开发者的女儿的名字. 1. 安 ...
- 微信小程序开发(四)线程架构和开发步骤
线程架构 从前面的章节我们可以知道,.js文件是页面逻辑处理层.我们可以按需在app.js和page.js中添加程序在生命周期的每个阶段相应的事件.如在页面的onLoad时进行数据的下载,onShow ...