八十道POJ了,加油!
题意:
线段上每个点有一个值,多次询问某些区间最大值和最小值的差。
裸的sparse-table解决RMQ,当然用线段树也一样,RMQ一定注意边界情况想清楚,否则样例一水WA都不知道怎么WA的。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
using namespace std;
#define mxn 200010
#define logmxn 50
int maxx[mxn][logmxn],minn[mxn][logmxn];
int h[mxn];
int n,q;
void set(){
for(int i=0;i<n;++i) maxx[i][0]=minn[i][0]=h[i];
for(int j=1;(1<<j)<=n;++j)
for(int i=0;i+(1<<j)<=n;++i){
maxx[i][j]=max(maxx[i][j-1],maxx[i+(1<<(j-1))][j-1]);
minn[i][j]=min(minn[i][j-1],minn[i+(1<<(j-1))][j-1]);
}
}
int ans(int l,int r){
int k=0;
while(l+(1<<(k+1))<=r+1) ++k;
return max(maxx[l][k],maxx[r-(1<<k)+1][k])-min(minn[l][k],minn[r-(1<<k)+1][k]);
}
int main(){
while(scanf("%d%d",&n,&q)!=EOF){
for(int i=0;i<n;++i) scanf("%d",&h[i]);
set();
int l,r;
for(int i=0;i<q;++i){
scanf("%d%d",&l,&r);
printf("%d\n",ans(l-1,r-1));
}
}
return 0;
}