ST 表

  • ST 表

例题

【模板】ST表

原理

在处理静态区间最大值的问题时,我们可以使用 ST 表(倍增思想)。

ST 表的原理是预处理序列中每一个数 a[i] ,使用 f[i][j] 去维护从 a[i] 开始的 \(2^{j}\) 个数中的最大值(包括 a[i])。

在查询区间 \([l,r]\) 中最大值的时候,设 \(j\) 是使 \(2^{j} <= r - l + 1\) 的最大整数。我们只需要找到两段长为 \(2^{j}\) 的区间,第一段以 a[l] 为起点,第二段以 a[r] 为终点,分别查询它们的最大值,再取其中的最大值,即可找到整段区间的最大值。

代码

#include <iostream>
#include <cmath>
using namespace std;
int N, M;
int f[100005][30];//f[i][j]表示从a[i]开始的2^j个数中的最大值(包括i)
inline int read()
{
	int x = 0, f = 1; char ch = getchar();
	while (ch < '0' || ch>'9') { if (ch == '-') f = -1; ch = getchar(); }
	while (ch >= '0' && ch <= '9') { x = x * 10 + ch - 48; ch = getchar(); }
	return x * f;
}
inline void put(int x)
{
	if (x > 9) put(x / 10);
	putchar(x % 10 + 48);
}
int main()
{
	cin >> N >> M;
	for (int i = 1; i <= N; i++)
	{
		f[i][0] = read();
	}
	for (int j = 1; j <= log(N) / log(2); j++)
	{
		for (int i = 1; i <= N - (1<<j) + 1; i++)
		{
			f[i][j] = max(f[i][j - 1], f[i + (1 << (j - 1))][j - 1]);
		}
	}


	while (M--)
	{
		int l, r;
		l = read();
		r = read();
		int x = log(r - l + 1) / log(2);
		put(max(f[l][x], f[r - (1<<x) + 1][x]));
		putchar('\n');
	}
	return 0;
}
posted @ 2023-08-16 22:15  susenyang  阅读(49)  评论(0)    收藏  举报