st表总结

简介\color{#88FF88}\textbf{简介}

st 表也可以翻译为稀疏表。

被用于解决 RMQ,gcdRMQ,\gcd 问题(区间最值),O(nlogn)O(n \log n) 预处理,O(1)O(1) 查询。

问题要满足可重复贡献。例如 max(aLR)\max(a_{L\to R}) 。 即可以表示为 max(aLk,ak+1R)\max(a_{L\to k},a_{k+1\to R}),也可表示为 max(aLR1,al+1R)\max(a_{L\to R-1},a_{l+1\to R})。即使可能有重复的部分,也没有影响。

推导与使用\color{#88FF88}\textbf{推导与使用}

基于这种思路,我们就可以通过倍增,动态规划的思想实现。以下为区间最大值的推导。定义 fi,jf_{i,j} 为从 ii 开始,长度为 2j2^j 的最大值。

状态方程就是:

fi,j=max(fi,j1,fi+2j1,j1)f_{i,j}=max(f_{i,j-1},f_{i+2^{j-1},j-1})

aia_i 即为 fi,0f_{i,0} 的最大值(区间长度为 11)。

代码\color{#88FF88}\textbf{代码}

for(int j=1;j<=LogN;j++) {
		for(int i=1;i+(1<<j)-1<=n;i++) {
			st[i][j]=max(st[i][j-1],st[i+(1<<(j-1))][j-1]);
		}
	}

查询\color{#88FF88}\textbf{查询}

根据前文,我们可在 O(1)O(1) 的时间复杂度内查询从 ii 开始,长度为 2j2^j 的区间。查询操作就是把大区间变成两个可能有重复的,小的,长度为 2j2^j 的区间。

例如 125125 ,可以被分解为 [1,64],[62,125][1,64],[62,125] 两个区间。

以下是查询区间 [l,r][l,r] 长度为 NN 的区间。

区间长度\color{#88FF88}\textbf{区间长度}

在两个区间内包含,所以长度为 2log2N2^{\log_2N}。(指数向下取整)

小细节\color{#88FF88}\textbf{小细节}

如果每次求 log2N\log_2N 会很慢。预处理可以变成 O(1)O(1)

logi=logi2+1log_{i} =log_{\frac{i}{2}}+1。特别地,log1=0log_1=0

区间开头\color{#88FF88}\textbf{区间开头}
  • 第一个区间很好理解,从 ll 开始。

  • 第二个区间知道结尾,与长度,计算得出从 N2log2N+1N-2^{\log_2N}+1 开始。

一些练习(可能按照难度排序)\color{#88FF88}\textbf{一些练习(可能按照难度排序)}

  1. JSOI2008-最大数\color{#A0F0FF}\small\textbf{\textsf{JSOI2008-最大数}}

改变一般 st 表的结构,从以 ii 开头,变成以 ii 结尾,使 st 表可更新元素。

同时有个小技巧,st 表也可以存储下标,达到与存最大值相同效果。

  1. 章节划分\color{#A0F0FF}\small\textbf{\textsf{章节划分}}

一道比较难的蓝题,结合了分治,递归,挺难想的。

  1. CERC2013-Magical GCD\color{#A0F0FF}\small\textbf{\textsf{CERC2013-Magical GCD}}

结合二分,其实也不算难。

  1. NOI2010-超级钢琴\color{#A0F0FF}\small\textbf{\textsf{NOI2010-超级钢琴}}

思维难度挺大的,不是很会想,锻炼一下思维吧,特别是结合了优先队列优化时间,贪心的思想很重要,也是我自己弄懂的第一道紫,挺有纪念意义的。自己的题解

posted @ 2023-05-23 15:28  cjrqwq  阅读(17)  评论(0)    收藏  举报  来源