【树论】RMQ问题和ST表
RMQ问题
RMQ(Range Maximum/Minimum Query)问题,即区间最值问题。
一般是多次询问,对时间复杂度要求高,一般需要
ST表#
p[i][j]
是以i为起点,连续
3 | 9 | 4 | 2 | 1 | 6 | 8 | 5 | |
---|---|---|---|---|---|---|---|---|
p[i][0] |
3 | 9 | 4 | 2 | 1 | 6 | 8 | 5 |
p[i][1] |
9 | 9 | 4 | 2 | 6 | 8 | 8 | - |
p[i][2] |
9 | 9 | 6 | 8 | 8 | - | - | - |
p[i][3] |
9 | - | - | - | - | - | - | - |
优缺点#
优点:可查询,可在末尾插入删除
缺点:不能修改
实现#
递推#
查询#
令 k = r-l+1;
int t = log2(k);
ans = max(p[l][t], p[r-(1<<t)+1][t]);
复杂度#
代码#
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cmath>
#pragma GCC optimize (3) // O(3)
using namespace std;
int p[100010][20], lg[100010];
inline int read()
{
int x=0,f=1; char ch=getchar();
while (ch<'0'||ch>'9') { if (ch=='-') f=-1; ch=getchar(); }
while (ch>='0'&&ch<='9') { x=x*10+ch-48; ch=getchar(); }
return x*f;
}
int main()
{
ios::sync_with_stdio(false);
int n, m;
n=read();m=read();
for(int i = 1;i <= n;i++) p[i][0]=read();
for(int j = 1;(1<<j) <= n;j++)
for(int i = 1;i+(1<<j-1) <= n;i++)
p[i][j] = max(p[i][j-1], p[i+(1<<j-1)][j-1]);
lg[1] = 0;
for(int i = 2;i <= n;i++) lg[i] = lg[i>>1] + 1;
while(m--)
{
int l, r;
l=read();r=read();
int t = lg[r-l+1];
printf("%d\n",max(p[l][t], p[r-(1<<t)+1][t]));
}
return 0;
}
技巧-快速读入
inline int read()
{
int x=0,f=1; char ch=getchar();
while (ch<'0'||ch>'9') { if (ch=='-') f=-1; ch=getchar(); }
while (ch>='0'&&ch<='9') { x=x*10+ch-48; ch=getchar(); }
return x*f;
}
背下来就好了
作者:蒟蒻Ivan
出处:https://www.cnblogs.com/ghivan911/p/17654080.html
版权:本作品采用「转载请注明出处-非商业性使用」许可协议进行许可。
本博文版权归本博主所有,未经授权不得转载
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战