「学习笔记」倍增求RMQ

RMQ,即区间最值查询,给定一个序列,求区间 lr 的最大值、最小值。
ST 表求 RMQ,预处理 Onlogn ,查询 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]);//取最大值 
        }
    }
}

查询:#

这里 lr 不一定刚好是 2j,这里要么越界,要么有重复。
我们是求最值,又不是求和,有没有重复又有什么关系呢?那我们就让他有重复的部分。
代码:

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]);//这里有重合部分,但重合部分取最大值不影响最后结果(又不是求和) 
}

一道简单的例题:#

题目传送门
代码:

#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;
}

作者:yifan0305

出处:https://www.cnblogs.com/yifan0305/p/16455525.html

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

转载时还请标明出处哟!

posted @   yi_fan0305  阅读(51)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
more_horiz
keyboard_arrow_up light_mode palette
选择主题
menu
点击右上角即可分享
微信分享提示