A61578 | RMQ区间最值问题)给定序列a0, … ,an-1,和m次询问,每次询问给定l,r,求max {al, … ,ar}为了解决该问题,有一个算法叫theMethodofFourRussians,其时间复杂度为O(n+m),步骤如下:·建立 Cartesian(笛卡尔)树,将问题转化为树上的 LCA(最近公共祖先)问题。·对于 LCA问题,可以考虑其 Euler序(即按照 DFS过程,经过所有点,环…
来源2021年
时间限制1s
内存限制256MB
通过 / 提交0/0
题目描述
RMQ区间最值问题)给定序列a0, … ,an-1,和m次询问,每次询问给定l,r,求max {al, … ,ar}
为了解决该问题,有一个算法叫theMethodofFourRussians,其时间复杂度为O(n+m),步骤如下:
·建立 Cartesian(笛卡尔)树,将问题转化为树上的 LCA(最近公共祖先)问题。
·对于 LCA问题,可以考虑其 Euler序(即按照 DFS过程,经过所有点,环游回根的序列),即求 Euler序列上两点间一个新的 RMQ问题。
·注意新的问题为 ±1RMQ,即相邻两点的深度差一定为 1。
下面解决这个 ±1RMQ问题,“序列”指 Euler序列:
·设t为 Euler序列长度。取b=[]。将序列每b个分为一大块, 使用 ST表(倍增表)处理大块间的 RMQ问题,复杂度O(logt)=O(n)。
·(重点)对于一个块内的 RMQ问题,也需要O(1) 的算法。由于差分数组 2b-1种,可以预处理出所有情况下的最值位置,预处理复杂度O(b2b),不超过O(n
)。
·最终,对于一个查询,可以转化为中间整的大块的 RMQ问题,以及两端块内的 RMQ问题。
试补全程序。
#include <iostream>
#include <cmath>
using namespace std;
const int MAXN = 100000, MAXT = MAXN << 1;
const int MAXL = 18, MAXB = 9, MAXC = MAXT / MAXB;
struct node {
int val;
intdep, dfn, end;
node *son[2]; // son[0], son[1] 分别表示左右儿子
} T[MAXN];
int n, t, b, c, Log2[MAXC + 1];
int Pos[(1 << (MAXB - 1)) + 5], Dif[MAXC + 1];
node *root, *A[MAXT], *Min[MAXL][MAXC];
void build() { // 建立 Cartesian 树
static node *S[MAXN + 1];
int top = 0;
for (int i = 0; i < n; i++) {
node *p = &T[i];
while(top && S[top]->val < p->val)
①;
if (top)
②;
S[++top] = p;
}
root = S[1];
}
void DFS(node *p) { // 构建 Euler 序列
A[p->dfn = t++] = p;
for (int i = 0; i < 2; i++)
if (p->son[i]) {
p->son[i]->dep = p->dep + 1;
DFS(p->son[i]);
A[t++] = p;
}
p->end = t 1;
}



暂无题解
C++ 编辑器
输入
输出
可保存默认模板;新题优先使用已保存模板。
当前快捷键仅展示,暂不支持修改。
- 撤销
Ctrl / ⌘ + Z - 重做
Ctrl / ⌘ + Y - 查找
Ctrl / ⌘ + F - 全选
Ctrl / ⌘ + A - 复制
Ctrl / ⌘ + C - 剪切
Ctrl / ⌘ + X - 粘贴
Ctrl / ⌘ + V - 自动排版
工具栏排版按钮 - 草稿保存
编辑时自动保存到本机
历史
提交记录
状态说明时间源码
AI
作答助手
你好,我是作答助手。可以问思路、复杂度、样例含义或代码报错原因;不会直接给出完整 AC 代码。
确定要清空代码吗?