数据结构·ST表

ST表(Sparse Table)

可重复贡献问题

  • x o p t x = x x \ opt\ x = x x opt x=x :如果两个区间重复计算某些元素时,对重复元素 进行 o p t opt opt操作没有任何影响

理解

ST表的思想是倍增,每一次处理上一次处理的两倍的元素 ,倍增的方式有重叠部分,如果重叠部分可重复贡献,则倍增的思路是正确的。

  • 长度:int len=log2(n),向下取整,避免出现无效元素参与计算
  • 构造时的递推公式:amax[j][m] = max(amax[j - 1][m], amax[j - 1][m + (1 << j - 1)]),例子:第3层第1个元素,由第2层第1,2,3个元素累积得到,其中第二个元素出现重复。
  • query:max(amax[len][l], amax[len][r - (1 << len) + 1]),首先查询当前层l处的元素,然后考虑当前层代表了 2 l e n 2^{len} 2len个元素,由第一层元素反推第len层元素。

模板

  • init()操作: O ( n l o g n ) O(nlogn) O(nlogn)复杂度
cpp 复制代码
		int len = log2(n);
		for (int j = 1; j <= len; j++) {
			for (int m = 1; m <= n - (1 << j) + 1; m++) {
				amax[j][m] = max(amax[j - 1][m], amax[j - 1][m + (1 << j - 1)]);
				amin[j][m] = min(amin[j - 1][m], amin[j - 1][m + (1 << j - 1)]);
			}
		}
  • query()操作: O ( 1 ) O(1) O(1),仅仅支持静态查询,不支持任意修改方式
cpp 复制代码
int query(int l,int r,int flag) {//flag==1 max
	int len = log2(r - l + 1);
	if (flag)return max(amax[len][l], amax[len][r - (1 << len) + 1]);
	return min(amax[len][l], amax[len][r - (1 << len) + 1]);
}
  • 优化:log2操作比较费时,所以可以采用dp方式优化该运算。
cpp 复制代码
lg[0]=-1;
for(int i=1;i<=n;i++)lg[i]=lg[i>>1]+1;

例题

P7333 [JRKSJ R1] JFCA:环的处理,二分的选择。

P10059 Choose:二分,注意到当L=n-k+1时,就能取到X的最大值,且L的取值与取到X的最大值有单调关系,使用二分。

相关推荐
晚云与城11 分钟前
【数据结构】-----排序的艺术画卷
数据结构·算法·排序算法
j_xxx404_1 小时前
数据结构:算法复杂度与空间复杂度
c语言·数据结构·算法
自由随风飘2 小时前
旅游城市数量最大化 01背包问题
数据结构·c++·算法·动态规划·旅游
好好先森&3 小时前
C语言:冒泡排序
c语言·数据结构·算法·遍历·冒牌排序
肉夹馍不加青椒4 小时前
第二十三天(数据结构:链表补充【希尔表】)
数据结构·链表
草莓熊Lotso5 小时前
【LeetCode刷题指南】--单值二叉树,相同的树
c语言·数据结构·算法·leetcode·刷题
Asu52026 小时前
链表反转中最常用的方法————三指针法
java·数据结构·学习·链表
闪电麦坤956 小时前
数据结构:在链表中查找(Searching in a Linked List)
数据结构·链表
泥泞开出花朵8 小时前
LRU缓存淘汰算法的详细介绍与具体实现
java·数据结构·后端·算法·缓存
KarrySmile9 小时前
Day17--二叉树--654. 最大二叉树,617. 合并二叉树,700. 二叉搜索树中的搜索,98. 验证二叉搜索树
数据结构·算法·二叉树·二叉搜索树·合并二叉树·最大二叉树·验证二叉搜索树