题意:
给一个数列,有Q个查询,每次查询L,R区间的最大值和最小值,输出他们的差。
思路:
st表对于区间查询来说是特别方便的,维护两个二维数组,分别是代表某一个区间的最>大值和最小值,st[i][j] 表示第i个数字和其之后的2^j 个数字的最值。那么二重循环进
行比较。
- 值得一说的是:st用到的是二进制的运算,其快速是一个特点。具体函数看代码。
#include <iostream>
#include <cstdio>
using namespace std;
const int maxn = 50005;
int n,q;
int st1[maxn][30];
int st2[maxn][30];
void RMQ_inti()
{
for(int j = 1;(1 << j) <= n; j++) {
for(int i = 0;i + (1<<j) - 1 < n; i++) {
st1[i][j] = min(st1[i][j-1],st1[i + (1<<(j-1))][j-1]);
st2[i][j] = max(st2[i][j-1],st2[i + (1<<(j-1))][j-1]);
}
}
}
int RMQ1(int l,int r)
{
int k = 0;
while((1<<(k+1)) <= r - l + 1) k++;
return min(st1[l][k],st1[r-(1<<k)+1][k]);
}
int RMQ2(int l,int r)
{
int k = 0;
while((1<<(k+1)) <= r - l + 1) k++;
return max(st2[l][k],st2[r-(1<<k)+1][k]);
}
int main()
{
//freopen("in.txt","r",stdin);
scanf("%d%d",&n,&q);
for(int i = 0;i < n; i++) {
scanf("%d",&st1[i][0]);
st2[i][0] = st1[i][0];
}
RMQ_inti();
int ans1,ans2;
for(int i = 0;i < q; i++) {
int l,r;
scanf("%d%d",&l,&r);
ans1 = RMQ1(l-1,r-1);
ans2 = RMQ2(l-1,r-1);
printf("%d\n",ans2-ans1);
}
return 0;
}