/*
ST表:给定一段区间,求这段区间的最大/最小值
f[i][j]:记录[i~i+2^j-1]区间的最大值
状态转移:将[i,j]平均分成两段
f(i,j)的最大值即这两段的最大值中的最大值。
f[i][j]=max(f[i][j-1],f[i+2^j-1][j-1])
查询时给定l,r
取k=log2(r-l+1)
ans=max(f[l][k],f[r-2^k+1][k])
*/
#include <algorithm>
#include <cmath>
#include <cstdio>
using namespace std;
int a[100005],f[100005][25]={0};
int n;
void ST()
{
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]);
}
}
}
int RMQ(int l,int r)
{
int k=log2(r-l+1);
return max(f[l][k],f[r-(1<<k)+1][k]);
}
int main()
{
int m;
scanf("%d%d",&n,&m);
for(int i = 1; i <= n; i++)
{
scanf("%d",&a[i]);
}
ST();
for (int j = 1; j <= m; j++)
{
int x,y;
scanf("%d%d",&x,&y);
printf("%d\n",RMQ(x,y));
}
return 0;
}
复杂度:预处理O(nlogn),询问O(1)