P3865 【模板】ST 表 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int N = 1e5+10;
int mn[N];//mn[i]表示2^j<=i的j的最大值
int dp[N][20];//dp[i][j]表示[i][i+2^j]区间所维护值,其中2^20大约4e6
int a[N];
int n,m;
void init ()
{
mn[0]=-1;
for(int i = 1;i <= n; i++){
mn[i] = ((i&(i-1)) == 0)? mn[i-1]+1 : mn[i-1];//(i&(i-1)判断是否为2^j次
dp[i][0] = a[i];
}
for(int j = 1; j <= mn[n]; j++ )//从距离为2开始
for(int i = 1; i + (1 << j ) - 1<= n; i++)//右端点要<=n
dp[i][j] = max(dp[i][j-1],dp[i+(1 << (j-1))][j-1]);
}
int query(int l,int r){
int j = mn[r - l + 1];
return max (dp[l][j],dp[r-(1 << j) + 1][j]);
}
int main()
{
scanf("%d%d",&n, &m);
for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
init();
for(int i = 1; i <= m; i++) {
int l, r;
scanf("%d%d",&l, &r);
printf("%d\n",query(l,r));
}
return 0;
}