ST表
给定一个长度为
的序列,查询
次
的极值。(RMQ问题)
(比线段树的常数小,代码简短。但是不支持修改且只能用于查询极值)
1.
表示第
个数到往后
范围内(包括自身) 的极值
2.需要用
的预处理 处理出
所储存的信息,转移过程取极值是利用
原理。
3.查询区间长度为
时, 令
,把原区间分为
和
。两个区间的长度大小都是
.两个区间的最值即为原区间最值。
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
int n,m,l,r;
int f[101010][20];
int main()
{
scanf("%d%d",&n,&m);
for(int i = 1; i <= n; i++)
scanf("%d",&f[i][0]);
for(int i = 1; i <= 20; i++)
for(int j = 1; j+(1<<i)-1 <= n; j++)
f[j][i] = max(f[j][i-1], f[j+(1<<i-1)][i-1]);
for(int i = 1; i <= m; i++)
{
scanf("%d%d",&l,&r);
int k = log(r-l+1) / log(2);
printf("%d\n",max(f[l][k], f[r-(1<<k)+1][k]));
}
return 0;
}