您的位置:首页 > 其它

POJ3264 Balanced Lineup(线段树)

2016-02-03 19:39 393 查看
题意:

输入一组数和一组区间,输出每个输入的区间内最大值与最小值的差

要点:

涉及到区间的一般就是线段树,学习了一下,这题是最基本的线段树应用,主要问题是时间比较紧。

这个博客讲的不错:点击打开链接

15137463Seasonal3264Accepted1408K2250MSC++1467B2016-02-03 17:43:34
#include<stdio.h>
#define maxn 50005
#define inf 100000000
#define max(a,b) a>b?a:b
#define min(a,b) a>b?b:a   //预处理器函数
int high[maxn];
int tmax[4 * maxn], tmin[4 * maxn];

void build(int node,int left,int right)  //建线段树函数
{
if (left == right)
{
tmax[node] = tmin[node] = high[left];
}
else
{
build(2 * node, left, (left + right) / 2);
build(2 * node + 1, (left + right) / 2 + 1, right);
tmax[node] = max(tmax[2 * node], tmax[2 * node + 1]); //tmax用来储存取最大值的对应结点值
tmin[node] = min(tmin[2 * node], tmin[2 * node + 1]); //tmin用来储存取最小值的对应结点值
}
}

int query_max(int node, int begin, int end, int left, int right)  //递归求所求区间的最大值
{
int p1, p2;
if (left > end || right < begin)
return -1;
if (left <= begin&&right >= end)
return tmax[node];
int mid = (begin + end) / 2;
p1 = query_max(2 * node, begin, mid, left, right);
p2 = query_max(2 * node + 1, mid + 1, end, left, right);
return max(p1, p2);
}
int query_min(int node, int begin, int end, int left, int right)  //求最小值
{
int p1, p2;
if (left > end || right < begin)      //所求区间和当前区间没有交集
return inf;                       //返回一个很大的值,不影响后面比较
if (left <= begin&&right >= end)      //所求区间包含或与当前区间相等
return tmin[node];
int mid = (begin + end) / 2;
p1 = query_min(2 * node, begin, mid, left, right);
p2 = query_min(2 * node + 1, mid + 1, end, left, right);
return min(p1, p2);
}

int main()
{
int n, q,i,a, b;
while (scanf("%d%d", &n, &q) != EOF)
{
for (i = 1; i <= n; i++)
scanf("%d", &high[i]);
build(1, 1, n);
while (q--)
{
scanf("%d%d", &a, &b);
printf("%d\n", query_max(1, 1, n, a, b)-query_min(1,1,n,a,b));
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: