这是线段树的模板题,唯一的坑点就是我不知道为什么题目中说n<50000,但实际上我的结构体开到150000才够。后来想通了,n只是代表最底层的数目,而总数自然是要大于他的,我觉得两倍就行了,但用100000的话我不知道为什么不过。
#include <stdio.h>
const int maxn=500000+10;
int mi,ma;
struct btree
{
int l,r;
int max1,min1;
}tree[maxn];
int max(int x,int y)
{
if(x>y)
return x;
else
return y;
}
int min(int x,int y)
{
if(x<y)
return x;
else
return y;
}
void build(int l1,int r1,int k)
{
int mid=(l1+r1)/2;
tree[k].l=l1;
tree[k].r=r1;
tree[k].max1=0;
tree[k].min1=0x3f3f3f3f;
if(l1==r1) return ;
build(l1,mid,2*k);
build(mid+1,r1,2*k+1);
}
void insert(int v,int i,int k)
{
if(tree[k].l==tree[k].r)
{
tree[k].max1=v,tree[k].min1=v;
return ;
}
int mid=(tree[k].l+tree[k].r)/2;
if(i<=mid)
insert(v,i,2*k);
else
insert(v,i,2*k+1);
tree[k].max1=max(tree[2*k].max1,tree[2*k+1].max1);
tree[k].min1=min(tree[2*k].min1,tree[2*k+1].min1);
}
void search(int l1,int r1,int k)
{
if(tree[k].l==l1&&tree[k].r==r1)
{
mi=min(mi,tree[k].min1);
ma=max(ma,tree[k].max1);
return ;
}
int mid=(tree[k].l+tree[k].r)/2;
if(r1<=mid)
search(l1,r1,2*k);
else if(l1>=mid+1)
search(l1,r1,2*k+1);
else
{
search(l1,mid,2*k);
search(mid+1,r1,2*k+1);
}
}
int main()
{
int n,q;
scanf("%d%d",&n,&q);
int i;
build(1,n,1);
for(i=1;i<=n;i++)
{
int v;
scanf("%d",&v);
insert(v,i,1);
}
for(i=0;i<q;i++)
{
mi=0x3f3f3f3f;
ma=0;
int l,r;
scanf("%d%d",&l,&r);
search(l,r,1);
int ans=ma-mi;
printf("%d\n",ans);
}
return 0;
}