纯线段树模板(建树,查询)
For the daily milking, Farmer John’s N cows (1 ≤ N ≤ 50,000) always line up in the same order. One day Farmer John decides to organize a game of Ultimate Frisbee with some of the cows. To keep things simple, he will take a contiguous range of cows from the milking lineup to play the game. However, for all the cows to have fun they should not differ too much in height.
Farmer John has made a list of Q (1 ≤ Q ≤ 200,000) potential groups of cows and their heights (1 ≤ height ≤ 1,000,000). For each group, he wants your help to determine the difference in height between the shortest and the tallest cow in the group.
Input
Line 1: Two space-separated integers, N and Q.
Lines 2…N+1: Line i+1 contains a single integer that is the height of cow i
Lines N+2…N+Q+1: Two integers A and B (1 ≤ A ≤ B ≤ N), representing the range of cows from A to B inclusive.
Output
Lines 1…Q: Each line contains a single integer that is a response to a reply and indicates the difference in height between the tallest and shortest cow in the range.
输入样例:
6 3
1
7
3
4
2
5
1 5
4 6
2 2
输出样例:
6
3
0
题目大意:
每天挤奶时,农夫约翰的N头奶牛(1≤N≤50000)总是按相同的顺序排队。一天,农夫约翰决定组织一场终极飞盘游戏,和一些奶牛一起玩。为了简单起见,他将从挤奶阵容中挑选一组连续的奶牛来进行比赛。不过,要想让所有的奶牛都玩得开心,它们的身高不应该相差太大。
农夫约翰列出了Q(1≤Q≤200000)组奶牛群及其身高(1≤身高≤1000000)。对于每一组,他希望你帮助确定最矮和最高的牛之间的身高差。
输入
第1行: 两个空格分隔的整数,N和Q。
接下来: N行,每行包含一个整数,即奶牛i的高度
最后: Q组,每组两个整数A和B(1≤A≤B≤N),表示从A到B的奶牛范围。
输出
Q组,每组包含一个整数,指A到B范围内最高和最矮奶牛之间的身高差。
/*
k<<1 表示k*2
k<<1|1 表示k*2+1
k>>1 表示k/2
*/
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
typedef long long ll;//ll即为长整型
int a[50010];
int mintree[1000010],maxtree[1000010];
//建立最小树
void build_mintree(int node,int l,int r)
{
if(l==r)
mintree[node]=a[l];
else
{
int mid=(l+r)>>1;
build_mintree(node<<1,l,mid);
build_mintree(node<<1|1,mid+1,r);
mintree[node]=min(mintree[node<<1],mintree[node<<1|1]);//求区间最小值
}
}
//建立最大树
void build_maxtree(int node,int l,int r)
{
if(l==r)
maxtree[node]=a[l];
else
{
int mid=(l+r)>>1;
build_maxtree(node<<1,l,mid);
build_maxtree(node<<1|1,mid+1,r);
maxtree[node]=max(maxtree[node<<1],maxtree[node<<1|1]);
}
}
//区间查询最小值
ll query_mintree(int node,int l,int r,int x,int y)
{
if(x==l&&y==r)
return mintree[node];
else
{
int mid=(l+r)>>1;
if(y<=mid)
return query_mintree(node<<1,l,mid,x,y);
else if(x>mid)
return query_mintree(node<<1|1,mid+1,r,x,y);
else
return min(query_mintree(node<<1,l,mid,x,mid),query_mintree(node<<1|1,mid+1,r,mid+1,y));
}
}
//区间查询最大值
ll query_maxtree(int node,int l,int r,int x,int y)
{
if(x==l&&y==r)
return maxtree[node];
else
{
int mid=(l+r)>>1;
if(y<=mid)
return query_maxtree(node<<1,l,mid,x,y);
else if(x>mid)
return query_maxtree(node<<1|1,mid+1,r,x,y);
else
return max(query_maxtree(node<<1,l,mid,x,mid),query_maxtree(node<<1|1,mid+1,r,mid+1,y));
}
}
int main()
{
int n,q;
while(~scanf("%d%d",&n,&q))
{
int x,y,i;
for(i=1; i<=n; i++)
scanf("%d",&a[i]);
build_mintree(1,1,n);
build_maxtree(1,1,n);
for(i=0; i<q; i++)
{
scanf("%d%d",&x,&y);
ll s1=query_mintree(1,1,n,x,y);//查询区间最小值
ll s2=query_maxtree(1,1,n,x,y);//查询区间最大值
printf("%lld\n",s2-s1);
}
}
return 0;
}