RMQ,即区间最值查询,给定一个序列,求区间l-r的最大值、最小值。

st表求RMQ,预处理On*logn,查询O1

预处理:

void init_rmq()
{
for(rll j=1;j<=lg[n];++j)//从当前点开始的2的j次方个点
{
for(rll i=1;(i+(1<<j)-1)<=n;++i)//i+(1<<j)-1不能越界
{
f[i][j]=max(f[i][j-1],f[i+(1<<(j-1))][j-1]);//取最大值
}
}
}

查询:

这里l到r不一定刚好是2^j,这里要么越界,要么有重复。

我们是求最值,又不是求和,有没有重复又有什么关系呢?那我们就让他有重复的部分。

代码:

ll rmq(ll l,ll r)
{
ll k=log(r-l+1)/log(2);//处理log
return max(f[l][k],f[r-(1<<k)+1][k]);//这里有重合部分,但重合部分取最大值不影响最后结果(又不是求和)
}

一道简单的例题:

信息学奥赛一本通(C++版)在线评测系统 (ssoier.cn)

代码:

#include<bits/stdc++.h>
#define ll long long
#define rint register int
#define rll register long long
using namespace std;
const ll N=1e5+5;
ll n,m;
ll f[N][20];
int lg[N];
inline ll read()
{
ll x=0;
bool flag=false;
char ch=getchar();
while(ch<'0'||ch>'9')
{
if(ch=='-') flag=true;
ch=getchar();
}
while(ch>='0'&&ch<='9')
{
x=(x<<3)+(x<<1)+(ch^'0');
ch=getchar();
}
return flag?~x+1:x;
}
void init_rmq()
{
for(rll j=1;j<=lg[n];++j)//从当前点开始的2的j次方个点
{
for(rll i=1;(i+(1<<j)-1)<=n;++i)//i+(1<<j)-1不能越界
{
f[i][j]=max(f[i][j-1],f[i+(1<<(j-1))][j-1]);//取最大值
}
}
}
ll rmq(ll l,ll r)
{
ll k=log(r-l+1)/log(2);//处理log
return max(f[l][k],f[r-(1<<k)+1][k]);//这里有重合部分,但重合部分取最大值不影响最后结果(又不是求和)
}
int main()
{
n=read(),m=read();//n 点的个数 m 操作数
for(rll i=1;i<=n;++i)
{
f[i][0]=read();//读入数据
}
for(rint i=1;i<=n;++i)
{
lg[i]=lg[i-1]+(1<<lg[i-1]==i);//处理log
}
init_rmq();//初始化
for(rll l,r,i=1;i<=m;++i)
{
l=read(),r=read();
printf("%lld\n",rmq(l,r));//查询
}
return 0;
}

倍增求RMQ的更多相关文章

  1. 倍增求LCA学习笔记(洛谷 P3379 【模板】最近公共祖先(LCA))

    倍增求\(LCA\) 倍增基础 从字面意思理解,倍增就是"成倍增长". 一般地,此处的增长并非线性地翻倍,而是在预处理时处理长度为\(2^n(n\in \mathbb{N}^+)\ ...

  2. 树上倍增求LCA(最近公共祖先)

    前几天做faebdc学长出的模拟题,第三题最后要倍增来优化,在学长的讲解下,尝试的学习和编了一下倍增求LCA(我能说我其他方法也大会吗?..) 倍增求LCA: father[i][j]表示节点i往上跳 ...

  3. [算法]树上倍增求LCA

    LCA指的是最近公共祖先(Least Common Ancestors),如下图所示: 4和5的LCA就是2 那怎么求呢?最粗暴的方法就是先dfs一次,处理出每个点的深度 然后把深度更深的那一个点(4 ...

  4. 【倍增】洛谷P3379 倍增求LCA

    题目描述 如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 输入输出格式 输入格式: 第一行包含三个正整数N.M.S,分别表示树的结点个数.询问的个数和树根结点的序号. 接下来N-1行每 ...

  5. 模板 倍增维护RMQ

    倍增维护RMQ,nlogn预处理,O(1)查询 #include<bits/stdc++.h> using namespace std; const int maxn = 1e5+7; s ...

  6. hdu 2586 How far away ? 倍增求LCA

    倍增求LCA LCA函数返回(u,v)两点的最近公共祖先 #include <bits/stdc++.h> using namespace std; *; struct node { in ...

  7. 倍增求lca模板

    倍增求lca模板 https://www.luogu.org/problem/show?pid=3379 #include<cstdio> #include<iostream> ...

  8. 【题解】洛谷P4180 [BJWC2010] 严格次小生成树(最小生成树+倍增求LCA)

    洛谷P4180:https://www.luogu.org/problemnew/show/P4180 前言 这可以说是本蒟蒻打过最长的代码了 思路 先求出此图中的最小生成树 权值为tot 我们称这棵 ...

  9. 树链剖分与倍增求LCA

    树链剖分与倍增求\(LCA\) 首先我要吐槽机房的辣基供电情况,我之前写了一上午,马上就要完成的时候突然停电,然后\(GG\)成了送链剖分 其次,我没歧视\(tarjan LCA\) 1.倍增求\(L ...

随机推荐

  1. 树莓派开发笔记(十四):入手研华ADVANTECH工控树莓派UNO-220套件(三):使用研发自带系统测试rtc、gpio、232和485套件接口

    前言   上一篇说明了必须要使用研华自带的8G卡的系统,通过沟通拿到了相关的系统,购买的时候会带8GB的卡,请自行备份一份镜像.本篇对uno-220套件的相关研华配套的额外接口做测试,篇幅较长,重点讲 ...

  2. Git移除远程已经上传的文件

    我们常常会将本地的一些秘钥文件不小心推送到远端,此时仅仅修改本地的.gitignore文件,然后再提交推送是不能将远端的此文件删除的. 此时可以用下面的命令 git rm --cached filen ...

  3. declare-声明限定类型变量

    用于声明变量并设置变量的属性. 语法 declare [+/-][rxi][变量名称=设置值] declare -f 特殊符号 +/- "-"可用来指定变量的属性,"+& ...

  4. 利用 Onekey Theater 改善屏幕显示效果

    介绍 Onekey Theater(一键影音),它是联想笔记本带的一键影音功能,使用它能够更改笔记本的显示效果和音效,以此模仿电影院的效果,为用户带来更好是视听效果及享受. 作用 之前的联想笔记本自带 ...

  5. 《Unix 网络编程》11:名字和地址转换

    名字和地址转换 系列文章导航:<Unix 网络编程>笔记 域名系统 简介 域名系统主要用于主机名字和 IP 地址之间的映射.主机名可以是: 简单名字,如:centos01 全限定域名(FQ ...

  6. CSP-J游记

    祝大家 CSP-J/CSP-S 稳过第一轮 ~(- ∨ -)~ ~~ 建议扩大110%食用 ~~ 中秋快乐鸭(希望大家不会收到损友送的砖头月饼 : − ) :-) :−)) 咳咳,昨天是我们可爱初赛来 ...

  7. 2021蓝桥杯省赛C++A组试题E 回路计数 状态压缩DP详细版

    2021蓝桥杯省赛C++A组试题E 回路计数 状态压缩DP 题目描述 蓝桥学院由21栋教学楼组成,教学楼编号1到21.对于两栋教学楼a和b,当a和b互质时,a和b之间有一条走廊直接相连,两个方向皆可通 ...

  8. 国外卡组织的 交换费-interchangefee(发卡行服务费) 和 银联对比

    本文地址:https://www.cnblogs.com/hchengmx/p/15170391.html 1. 交换费(interchangefee)介绍 2. MasterCard 万事达卡 &a ...

  9. USB机械键盘改蓝牙键盘

    手里有两把机械键盘,一个是IKBC 87键,一个是IKBC POKER II 60键,由于买的比较早,两把键盘均为USB的,使用起来桌面线比较多,碍事,于是开始研究如何改成蓝牙键盘. 首先说一下USB ...

  10. 剖析 SPI 在 Spring 中的应用

    vivo 互联网服务器团队 - Ma Jian 一.概述 SPI(Service Provider Interface),是Java内置的一种服务提供发现机制,可以用来提高框架的扩展性,主要用于框架的 ...