```
//ST表模板
//预处理 O(nlogn),处理O(1),空间O(nlogn)。
#include<iostream>
using namespace std;
const int N = 100006;
int dp[N][25]; //区间最小值
int mn[N]; //存储分割点
int a[N]; //存储数据
int n;
/*dp公式
例dp[5][3] = min(dp[5][2],dp[9][2]);
等价于min(5,12) = min(min(5...8),min(9...12));
又例min(5,14) = min(min(5...12),min(13...14))
= min(min(5...8),min(9...12),min(13...14)
= min(min(5...6),min(7...8),min(9...10),min(11...12),min(13...14);
等价于min(dp[5][3],dp[13][1]);
特例min(5,15)= min(dp[5][3],dp[12][2]);
= min(min(5...12),min(12...15));
dp[x][y],左端点为x,右端点为x+2^y-1 */
void init()
{
for(int i=1; i<=n; i++)
dp[i][0] = a[i];
for(int j=1; (1<<j)<=n; j++)
for(int i=1; i+(1<<j)-1<=n; i++)
dp[i][j] = min(dp[i][j-1],dp[i+(1<<(j-1))][j-1]);
for(int len=1;len<=n;++len)
{
int k = 0;
while((1<<(k+1))<=len)
k++;
mn[len] = k;
}
}
int rmq(int L,int R)
{
int k=mn[R-L+1];
return min(dp[L][k],dp[R-(1<<k)+1][k]);
}
int main()
{
int m; cin >> n >> m;
for(int i=1; i<=n; i++) cin >> a[i];
init();
for(int i=0; i<m; i++)
{
int l,r; cin >> l >> r;
cout << rmq(l,r) << endl;
}
return 0;
}
“`