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;
}