实现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客户端,只 ...
随机推荐
- [DeeplearningAI笔记]卷积神经网络2.5-2.7 Network in Network/1*1卷积/Inception网络/GoogleNet
4.2深度卷积网络 觉得有用的话,欢迎一起讨论相互学习~Follow Me 参考文献 Inception网络 --Szegedy C, Liu W, Jia Y, et al. Going deepe ...
- 利用Tensorflow读取二进制CIFAR-10数据集
使用Tensorflow读取CIFAR-10二进制数据集 觉得有用的话,欢迎一起讨论相互学习~Follow Me 参考文献 Tensorflow官方文档 tf.transpose函数解析 tf.sli ...
- libcurl在mingw下编译
通过命令提示符进入 curl-7.27.0 文件夹输入 mingw32-make mingw32 进行生成(这里我只需要普通的功能,于是没有加附加的选项)编译完成后,在 lib 文件夹中会有我们需要的 ...
- 1.ideal常用快捷键
Alt+回车 导入包,自动修正Ctrl+N 查找类Ctrl+Shift+N 查找文件Ctrl+Alt+L 格式化代码 Ctrl+Alt+O 优化导入的类和包Alt+Insert 生成代码(如ge ...
- NOIP 2000 方格取数
https://www.luogu.org/problem/show?pid=1004 题目描述 设有N*N的方格图(N<=9),我们将其中的某些方格中填入正整数,而其他的方格中则放 人数字0. ...
- Anagrams by Stack(深度优先搜索)
ZOJ Problem Set - 1004 Anagrams by Stack Time Limit: 2 Seconds Memory Limit: 65536 KB How can a ...
- docker-compose写法收集
version: '3.3' services: php: image: docker.ksyun.com/php7.:latest volumes: - ./env/log/apps:/data/l ...
- PowerShell入门
最近需要写个Windows的脚本,以前一直使用cmd.exe来写批处理脚本,这次接触到了PowerShell,准备把学习过程中学到的知识点整理在这里: 相关文章: 1.https://www.cnbl ...
- scrapy 爬虫踩过的坑(I)
问题1:正则表达式没问题,但是爬虫进不了item方法 分析: 1. 可能是下载不到list 页面的内容.可以用 scrapy shell url 进行测试 2. 可能是allowed_domains ...
- Double类型的数向上取整和向下取整