总结:
其实ST表不仅能处理最大值/最小值,凡是符合结合律且可重复贡献的信息查询都可以使用ST表高效进行。什么叫可重复贡献呢?设有一个二元运算 ,满足 ,则是可重复贡献的。显然最大值、最小值、最大公因数、最小公倍数、按位或、按位与都符合这个条件。可重复贡献的意义在于,可以对两个交集不为空的区间进行信息合并。
1.最大最小值。
2.在单调序列中,相同数的最大个数。
预处理
cnt[i]每个位置相同数的个数。
last[i]表示每个位置相同数在哪里结束。
对于每次查询[L, R],处理左边界L。
如果last[L] == last[R],输出R - L + 1。
如果last[L] == last[L - 1],说明左边界截断了当前连续序列,同时也要保证ST表查询的序列是一个完整的,因此需要将last[L] - L + 1和ST(last[L] + 1, R)取最大。
其余情况直接输出ST(L, R)即可,因为此时左边界没有截断序列。
3.最大公因数。
4.不同数连续序列长度
预处理
len[i]表示以a[i]结尾的最长长度,用ST表维护len数组。
idx[i]表示当前最长序列的开头的坐标。
对于每次查询L, R。序列可能被L在中间截断,用二分找到这段序列结尾mid。除去这段序列,[mid + 1, R]所在的序列一定在[L, R]之内。
因为二分找的是idx[mid] < L 中最大的mid,保证了mid + 1这个序列的开头一定不小于L。