ST 表

ST 表
Zyx_2012关于 ST 表
用于
ST 表(即稀疏表,以下称 ST 表)可以用于频繁求区间最值的问题,普通算法每次请求复杂度为 O(n)
,ST 表预处理复杂度为 O(n+m)
,每次请求复杂度为 O(1)
原理
ST 表是将一个数组二分成很多小段,每一段求一个最值。若给出两个端点( l,r
),一定可以给出两个 ST 表中预处理过的区间,使得这两个区间覆盖了 l,r
间所有的端点,此时将这两个预处理过的区间的最值取一个最值,即可求得 l,r
间的最值
练习 & 实战
题目
题目描述
P1816 忠诚
题目描述
老管家是一个聪明能干的人。他为财主工作了整整 $10$ 年。财主为了让自已账目更加清楚,要求管家每天记 $k$ 次账。由于管家聪明能干,因而管家总是让财主十分满意。
但是由于一些人的挑拨,财主还是对管家产生了怀疑。于是他决定用一种特别的方法来判断管家的忠诚。他把每次的账目按 $1, 2, 3, \ldots$ 编号,然后不定时地问管家这样的问题:在 $a$ 到 $b$ 号账中最少的一笔是多少?
为了让管家没时间作假,他总是一次问多个问题。
输入格式
第一行输入两个数 $m, n$,表示有 $m$ 笔账和 $n$ 个问题。
第二行输入 $m$ 个数,分别表示账目的钱数。
接下来 $n$ 行分别输入 $n$ 个问题,每行 $2$ 个数字,分别表示开始的账目编号 $a$ 和结束的账目编号 $b$。输出格式
第一行输出每个问题的答案,每个答案中间以一个空格分隔。
输入输出样例 #1
输入 #1
1
2
3
4
5 10 3
1 2 3 4 5 6 7 8 9 10
2 7
3 9
1 10输出 #1
1 2 3 1说明 / 提示
对于 $100%$ 的数据,$1 \leq m \leq 10^5$,$1 \leq n \leq 10^5$。
代码思路
首先,这是一个 RMQ
题,所以要用到 ST 表。既然要用到 ST 表,那就要快读快写
1 | /* ------------------------------- FastIO ------------------------------- */ |
1 | { |
然后,我们要初始化一下:
1 | const int N = 1e5+5;//开大点 |
输入及初始 ST 表
1 | for (int i = 1; i <= n; i++) { |
预处理 log_2
1 | log_2[1] = 0; |
构建 ST 表
1 | for (int j = 1; j < Log; j++) { |
查询
1 | while (m--) { |
结尾
1 | return 0; |
代码完整版
1 |
|
评论
匿名评论隐私政策
✅ 你无需删除空行,直接评论以获取最佳展示效果