Balanced Lineup poj3264 线段树

Balanced Lineup poj3264 线段树

题意

一串数,求出某个区间的最大值和最小值之间的差

解题思路

使用线段树,来维护最大值和最小值,使用两个查询函数,一个查区间最大值,一个查区间最小值,然后做差就好了,基本上就是线段树模板题

代码实现

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
const int maxn=5e4+7;
struct node{
	int l, r, max, min;
}tre[maxn<<2];
int num[maxn];
int n, m;
void up(int rt)
{
    //为了效率使用了条件语句,但是好像也没有提高多少
	tre[rt].max=tre[rt<<1].max > tre[rt<<1|1].max ? tre[rt<<1].max : tre[rt<<1|1].max; 
	tre[rt].min=tre[rt<<1].min < tre[rt<<1|1].min ? tre[rt<<1].min : tre[rt<<1|1].min; 
}
void build(int rt, int l, int r) //正常的线段树建立函数
{
	tre[rt].l=l;
	tre[rt].r=r;
	if(l==r)
	{
		tre[rt].max=num[l];
		tre[rt].min=num[l];
		return ;
	}
	int mid=(l+r)>>1;
	build(rt<<1, l, mid);
	build(rt<<1|1, mid+1, r);
	up(rt);
}
int querymax(int rt, int L, int R)//寻找区间最大值
{
	if(L <= tre[rt].l && tre[rt].r <= R)
	{
		return tre[rt].max;
	}
	int mid=(tre[rt].l+tre[rt].r)>>1;
	int ans=0, tmp;
	if(L<=mid) 
	{
		tmp=querymax(rt<<1, L, R);
		ans= ans > tmp ? ans:tmp;
	}
	if(R>mid) 
	{
		tmp=querymax(rt<<1|1, L, R);
		ans= ans > tmp ? ans:tmp;
	}
	return ans;
}
int querymin(int rt, int L, int R)//寻找区间最小值
{
	if(L <= tre[rt].l && tre[rt].r <= R)
	{
		return tre[rt].min;
	}
	int mid=(tre[rt].l+tre[rt].r)>>1;
	int ans=inf, tmp;
	if(L<=mid) 
	{
		tmp=querymin(rt<<1, L, R);
		ans= ans < tmp ? ans:tmp;
	}
	if(R>mid) 
	{
		tmp=querymin(rt<<1|1, L, R);
		ans= ans<tmp ? ans:tmp;
	}
	return ans;
}
int main()
{
	int L, R, c;
	char s[4];
	while(scanf("%d%d", &n, &m)!=EOF)
	{
		for(int i=1; i<=n; i++)
		{
			scanf("%d", &num[i]);
		}
		build(1, 1, n);
		for(int i=1; i<=m; i++)
		{
			scanf("%d%d", &L, &R);
			printf("%ld\n", querymax(1, L, R)-querymin(1, L, R));
		}
	}
	return 0;
 } 
posted @ 2019-08-07 17:33  ALKING1001  阅读(95)  评论(0编辑  收藏  举报