题目大意:第一行输入两个整数n,m;第二行输入一个n个数的序列,第三行开始的m行,每行两个数a,b,分别表示一个操作,对于每个操作,要求输出该区间的最小值和最大值。
#include<stdio.h>
#include<string.h>
#define maxn 50010
#define MAX 1000005
#define MIN 0
struct node
{
int l,r;//线段树区间
int mid;//线段树区间中间值
int min,max;//
}p[maxn<<2];//注意这里不能写成p[maxn*2];否则RE
int min,max;
void build(int id,int l,int r)
{
p[id].l=l;
p[id].r=r;
p[id].mid=(l+r)>>1;
p[id].min=MAX;
p[id].max=MIN;
if(l==r) return;
build(2*id,l,p[id].mid);
build(2*id+1,p[id].mid+1,r);
}
void update(int id,int l,int r,int t,int val)
{
if(l<=t&&t<=r){
if(p[id].min>val) p[id].min=val;
if(p[id].max<val) p[id].max=val;
}
if(l==r) return;
if(p[id].mid>=t) update(2*id,l,p[id].mid,t,val);
else update(id*2+1,p[id].mid+1,r,t,val);
}
void query(int id,int l,int r,int a,int b)
{
if(l==a&&r==b){
if(min>p[id].min) min=p[id].min;
if(max<p[id].max) max=p[id].max;
return;
}
if(l==r) return;
if(p[id].mid>=b) query(id*2,l,p[id].mid,a,b);
else if(p[id].mid<a) query(id*2+1,p[id].mid+1,r,a,b);
else{
query(id*2,l,p[id].mid,a,p[id].mid);
query(id*2+1,p[id].mid+1,r,p[id].mid+1,b);
}
}
int main()
{
int n,m,i,j,x,y;
scanf("%d%d",&n,&m);
build(1,1,n);
for(j=0;j<n;j++)
{
scanf("%d",&x);
update(1,1,n,j+1,x);
}
for(i=0;i<m;i++)
{
scanf("%d%d",&x,&y);
min=MAX;
max=MIN;
query(1,1,n,x,y);
printf("%d\n",max-min);
}
return 0;
}
本文介绍了一种使用线段树进行区间最小值与最大值查询的方法。通过递归构建和更新线段树,实现对区间内元素的有效查找。文章详细展示了线段树的数据结构定义、构建过程、更新节点值及区间查询的具体实现。
220

被折叠的 条评论
为什么被折叠?



