题目大意:给定n个值,执行q次查询,输出区间最大值和区间最小值的差。
解题思路:维护两颗线段树,一颗维护区间最大值,一颗维护区间最小值即可。
做的时候忘了开4倍数组re了一次,cin、cout超时又tle了一次,可以说很蠢了emmmmmmm
#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
const int maxn = 5e4;
const int inf = 0x7f7f7f7f;
int Max[4*maxn + 5],Min[4*maxn + 5];
void build(int id,int l,int r)
{
if(l == r)
{
scanf("%d\n",&Max[id]);
Min[id] = Max[id];
return;
}
int mid = (l + r) >> 1;
build(id<<1,l,mid);
build(id<<1|1,mid+1,r);
Max[id] = max(Max[id<<1],Max[id<<1|1]);
Min[id] = min(Min[id<<1],Min[id<<1|1]);
}
int query_max(int id,int ql,int qr,int l,int r)
{
if(ql > r || qr < l) return 0;
if(l >= ql && r <= qr) return Max[id];
int mid = (l + r) >> 1;
return max(query_max(id<<1,ql,qr,l,mid),query_max(id<<1|1,ql,qr,mid+1,r));
}
int query_min(int id,int ql,int qr,int l,int r)
{
if(ql > r || qr < l) return inf;
if(l >= ql && r <= qr) return Min[id];
int mid = (l + r) >> 1;
return min(query_min(id<<1,ql,qr,l,mid),query_min(id<<1|1,ql,qr,mid+1,r));
}
int main()
{
int n,m;
scanf("%d%d",&n,&m);
build(1,1,n);
int l,r;
for(int i = 0;i < m;++i)
{
scanf("%d%d",&l,&r);
printf("%d\n", query_max(1,l,r,1,n) - query_min(1,l,r,1,n));
}
return 0;
}