【倍增】RMQ问题与ST表
问题叙述
RMQ 是 Range Maximum/Minimum Query 的缩写,表示区间最大/最小值。
显而易见的,可以用线段树写。但是我这样的蒟蒻早就忘了线段树怎么写了,而且由于该问题不涉及修改操作,所以线段树十分没有性价比。
这是就需要用到好理解又好写的ST表了。
算法思路
ST表是用于解决可重复贡献问题的数据结构。
倍增思想:我们考虑将
该如何处理转移过程?
把当前区间拆成两个大小相等的区间,用动态规划求出答案。
这样就可以保证该区间内所有的元素都被转移了。预处理就是将
查询过程?
查询过程也一样,分成两个区间,这里我用的是
其中的 k = log[r - l + 1]
,用于分隔两个区间。至于怎么求 lg[i] + 1
的写法,见下方代码。
总代码
例题:洛谷 P3865【模板】ST 表 && RMQ 问题
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
typedef long long ll;
const ll MAXN = 1e5 + 5;
ll st[MAXN][25], lg[MAXN];
ll Query(ll l, ll r){
ll k = lg[r - l + 1] - 1;
return max(st[l][k], st[r - (1 << k) + 1][k]);
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
ll n, m;
cin >> n >> m;
for(ll i = 1; i <= n; i ++){
cin >> st[i][0];
}
for(ll i = 1; i <= n; i ++){
lg[i] = lg[i - 1] + ((1 << lg[i - 1]) == i);
}
for(ll j = 1; j <= 20; j ++){
for(ll i = 1; i + (1 << j) - 1 <= n; i ++){
st[i][j] = max(st[i][j - 1], st[i + (1 << (j - 1))][j - 1]);
}
}
while(m --){
ll l, r;
cin >> l >> r;
cout << Query(l, r) << "\n";
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!