ST表是能够在o(nlgn)的预处理情况下,在o(1)的复杂度情况下来求一段区间的最小值和最大值,可以用来求重复贡献对问题答案没有影响的问题
为了减少时间复杂度,可以先预处理出lg2的数组,就不要每次都去用log函数
lg2[0] = -1 //方便求lg2循环数组
for(int i = 1; i <= n;i ++) lg2[i] = lg[i>>1] + 1;
然后再预处理每个区间的最大值和最小值
void init()
{
// 数组下标从1开始
for (int i = 1; i <= n; i++)f[i][0] = a[i];
for (int j = 1; (1 << j) <= n; j++)
{
for (int i = 1; i + (1 << j) - 1 <= n; i++)
{
f[i][j] = max(f[i][j - 1], f[i + (1 << j - 1)][j - 1]);
f[i][j] = min(f[i][j - 1], f[i + (1 << j - 1)][j - 1]);
}
}
}
最后就是O(1)的时间复杂度去询问每个区间的最大值和最小值,它是用两个区间取覆盖询问的区间,求着两个区间的最大值就询问区间的最大值
int query(int l, int r)
{
int k = lg2[r-l+1];
return max(f[l][k], f[r - (1 << k) + 1][k]);
}