题目是经典 查询区间最值问题
可以用RMQ线段树,或者st表
rmq线段树 建树 查询都是logn 支持更新元素
st表建树logn 查询o(1)! 不支持更新元素
以下是st表代码
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <iostream>
#include <queue>
#include <map>
#include <set>
#include <vector>
using namespace std;
const int maxn=50005;
int h[maxn];
int mx[maxn][16],mn[maxn][16];
int n,q;
int max(int a,int b)
{
if (a<b)
return b;
return a;
}
int min(int a,int b)
{
if (a>b)
return b;
return a;
}
void rmq_init()
{
int i,j;
for(j=1;j<=n;j++) mx[j][0]=mn[j][0]=h[j];
int m=floor(log((double)n)/log(2.0));
for(i=1;i<=m;i++){
for(j=n;j>0;j--){
mx[j][i]=mx[j][i-1];
if(j+(1<<(i-1))<=n) mx[j][i]=max(mx[j][i],mx[j+(1<<(i-1))][i-1]);
}
}
for(i=1;i<=m;i++){
for(j=n;j>0;j--){
mn[j][i]=mn[j][i-1];
if(j+(1<<(i-1))<=n) mn[j][i]=min(mn[j][i],mn[j+(1<<(i-1))][i-1]);
}
}
}
int rmq_max(int l,int r)
{
int m=floor(log((double)(r-l+1))/log(2.0));
int a=max(mx[l][m],mx[r-(1<<m)+1][m]);
return a; //a为最大值,b为最小值
}
int rmq_min(int l,int r)
{
int m=floor(log((double)(r-l+1))/log(2.0));
int b=min(mn[l][m],mn[r-(1<<m)+1][m]);
return b; //a为最大值,b为最小值
}
int main()
{
int i,a,b;
cin>>n>>q;
for (i=1;i<=n;i++)
cin>>h[i];
rmq_init();
for (i=1;i<=q;i++)
{
scanf("%d%d",&a,&b);
printf("%d\n",rmq_max(a,b)-rmq_min(a,b ));
}
return 0;
}
以下是线段树代码:
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <cstdio>
#include <algorithm>
#include <iostream>
#include <queue>
#include <set>
#include <vector>
#define inf 0x7fffffff
#define lson l , m , rt << 1
#define rson m + 1 , r , rt << 1 | 1
const int maxn = 50005;
int st_min[maxn<<2],st_max[maxn<<2];
int aa[maxn];
inline int minn(int a,int b) { return a>b?b:a; }
inline int maxx(int a,int b) { return a>b?a:b; }
void PushUP(int rt)
{
st_min[rt] = minn(st_min[rt<<1],st_min[rt<<1|1]);
st_max[rt] = maxx(st_max[rt<<1],st_max[rt<<1|1]);
}
int ok=0;
void build(int l,int r,int rt) {
if (l == r)
{ st_min[rt]=aa[++ok];
st_max[rt] = st_min[rt];
return ;
}
int m = (l + r) >> 1;
build(lson);
build(rson);
PushUP(rt);
}
int query_min(int L,int R,int l,int r,int rt)
{
if (L <= l && r <= R) {
return st_min[rt];
}
int m = (l + r) >> 1;
int ret1 = inf,ret2 = inf;
if (L <= m) ret1 = query_min(L , R , lson);
if (R > m) ret2 = query_min(L , R , rson);
return minn(ret1,ret2);
}
int query_max(int L,int R,int l,int r,int rt)
{
if (L <= l && r <= R) {
return st_max[rt];
}
int m = (l + r) >> 1;
int ret1 = -inf,ret2 = -inf;
if (L <= m) ret1 = query_max(L , R , lson);
if (R > m) ret2 = query_max(L , R , rson);
return maxx(ret1,ret2);
}
int main(void)
{
int n,m,i,a,b;
while(scanf("%d%d",&n,&m)!=EOF)
{
for (i=1;i<=n;i++)
scanf("%d",&aa[i]);
build(1 , n , 1);
for(i=1;i<=m;i++)
{
scanf("%d %d",&a,&b);
printf("%d\n",query_max(a,b,1,n,1)-query_min(a,b,1,n,1) );
}
}
return 0;
}