线段树的求区间最大值最小值的应用


#include "stdio.h"
#define N 50001
#define INF 0x7fffff
int n , q;
int maax , miin;
typedef struct
{
int l , r , max , min;
} node;
node tree[3*N];
void ini_tree(int i , int a , int b)
{
int mid = (a+b)/2;
tree[i].l = a;
tree[i].r = b;
tree[i].max = tree[i].min = 0;
if(a == b)
return ;
else
{
ini_tree(2*i,a,mid);
ini_tree(2*i+1,mid+1,b);
}
}
void insert(int p,int left,int right,int value)
{
int mid;
if(tree[p].r==right&&tree[p].l==left)
{
tree[p].min=value;
tree[p].max=value;
return ;
}
if(tree[p].max==0||tree[p].max<value)
tree[p].max=value;
if(tree[p].min==0||tree[p].min>value)
tree[p].min=value;
mid=(tree[p].r+tree[p].l)>>1;
if(right<=mid)
insert(2*p,left,right,value);
else if(left>=mid+1)
insert(2*p+1,left,right,value);
else
{
insert(2*p,left,mid,value);
insert(2*p+1,mid+1,right,value);
}
}
void query(int p,int left,int right)
{
int mid;
if(tree[p].r==right&&tree[p].l==left)
{
if(maax<tree[p].max)
maax=tree[p].max;
if(miin>tree[p].min)
miin=tree[p].min;
return ;
}
mid=(tree[p].l+tree[p].r)>>1;
if(right<=mid)
query(2*p,left,right);
else if(left>=mid+1)
query(2*p+1,left,right);
else
{
query(2*p,left,mid);
query(2*p+1,mid+1,right);
}
}
int main()
{
int i , a , b , value;
scanf("%d %d",&n,&q);
ini_tree(1,1,n);
for( i = 1 ; i <= n ; i++ )
{
scanf("%d",&value);
insert(1,i,i,value);
}
for( i = 1 ; i <= q ; i++ )
{
scanf("%d %d",&a,&b);
maax = 0 ;
miin = INF;
if( a == b )
{
printf("0\n");
continue;
}
else
{
query(1,a,b);
printf("%d\n",maax-miin);
}
}
return 0;
}