ST表
ST表
ST 表是用于解决 可重复贡献问题 的数据结构。可以在O(1)的时间复杂度内回答某一区间的最值查询(最小值、最大值等)。ST表使用动态规划和倍增的思想,通过预处理的方式来快速计算出各个区间的最值。
ST表的应用场合是有限的,它只能处理静态区间最值,不能维护动态的,也就是说不支持在预处理后对值进行修改。一旦修改,整张表便要重新计算,时间复杂度极高。动态最值可以用线段树、树状数组等来维护。
好的,以下是你提供的 C++ 代码,并且经过了排版和格式化,使其更加清晰:
建表部分
1 | // st[i][j] 表示以 i 为起点,包含 1<<j 个数的区间 |
查表部分
1 | // 定义两个变量 l, r 为查找区间的左右端点 |
预处理 log_2
1 | // 预处理 log_2[i],提高效率 |
代码解释
建表部分通过递推公式构建了一个二维数组
st
,每个st[i][j]
表示从i
开始,长度为2^j
的区间的和。这个表通过递推关系逐步计算得到。查表部分则使用预处理好的
log_2
数组,利用对数来快速判断区间长度,然后通过比较两个可能的区间来获取最终结果。这样做的好处是能在O(1)
时间内得到区间的最值。
其实到这已经结束了,上题目!
【模板】ST 表
题目背景
这是一道 ST 表经典题——静态区间最大值
请注意最大数据时限只有 0.8s,数据强度不低,请务必保证你的每次查询复杂度为 \(O(1)\)。若使用更高时间复杂度算法不保证能通过。
如果您认为您的代码时间复杂度正确但是 TLE,可以尝试使用快速读入:
1 | inline int read() |
函数返回值为读入的第一个整数。
快速读入作用仅为加快读入,并非强制使用。
题目描述
给定一个长度为 \(N\) 的数列,和 $ M $ 次询问,求出每一次询问的区间内数字的最大值。
输入格式
第一行包含两个整数 \(N,M\),分别表示数列的长度和询问的个数。
第二行包含 \(N\) 个整数(记为 \(a_i\)),依次表示数列的第 \(i\) 项。
接下来 \(M\) 行,每行包含两个整数 \(l_i,r_i\),表示查询的区间为 \([l_i,r_i]\)。
输出格式
输出包含 \(M\) 行,每行一个整数,依次表示每一次询问的结果。
样例 #1
样例输入 #1
1 | 8 8 |
样例输出 #1
1 | 9 |
1 |
|