Balanced Lineup(线段树求区间查询求最大最小值的差)(模板题)

该博客介绍了一种使用线段树数据结构解决区间查询问题的方法,特别是针对给定的一组奶牛身高数据,如何快速找到指定范围内奶牛的最大和最小身高差。通过建立最小树和最大树,实现O(logN)的时间复杂度内查询区间最大值和最小值,从而高效地回答查询请求。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

纯线段树模板(建树,查询)

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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值