题目大意:就是建立一个线段树,然后从1到n插入数字,然后查询几组区间,求这几组区间当中每一组区间最大值和最小值的差
代码(板子):
#include<iostream>
#include<cstdio>
using namespace std;
const int INF=0xfffff0;
int minV=INF;
int maxV=-INF;
struct Node{
int L,R;
int minV,maxV;
int Mid(){
return (L+R)/2;
}
};
Node tree[800010];
//4倍叶子节点的数
void BuildTree(int root,int L,int R){
tree[root].L=L;
tree[root].R=R;
tree[root].minV=INF;
tree[root].maxV=-INF;
//初始化最小的是最大的
//最大的是最小的
if(L!=R){
BuildTree(2*root+1,L,(L+R)/2);
BuildTree(2*root+2,(L+R)/2+1,R);
}
}
void Insert(int root,int i,int v){
if(tree[root].L==tree[root].R){
tree[root].minV=tree[root].maxV=v;
return ;
}
tree[root].minV=min(tree[root].minV,v);
tree[root].maxV=max(tree[root].maxV,v);
if(i<=tree[root].Mid())
Insert(2*root+1,i,v);
else
Insert(2*root+2,i,v);
}
void Query(int root,int s,int e){
if(tree[root].minV>=minV&&tree[root].maxV<=maxV)
return ;
if(tree[root].L==s&&tree[root].R==e){
minV=min(minV,tree[root].minV);
maxV=max(maxV,tree[root].maxV);
return ;
}
if(e<=tree[root].Mid())
Query(2*root+1,s,e);
else if(s>tree[root].Mid())
Query(2*root+2,s,e);
else{
Query(2*root+1,s,tree[root].Mid());
Query(2*root+2,tree[root].Mid()+1,e);
}
}
int main()
{
int n,q,h;
int i,j,k;
scanf("%d%d",&n,&q);
BuildTree(0,1,n);//以0为根节点,从1到n建树
for(int i=1; i<=n; i++)
{
scanf("%d",&h);
//第i个数,值为h插入线段树
Insert(0,i,h);
}
for(int i=0; i<q; i++)
{
//输入q个查询数
int s,e;
scanf("%d %d",&s,&e);
minV=INF;
maxV=-INF;
Query(0,s,e);
printf("%d\n",maxV-minV);
}
return 0;
}