您的位置:首页 > 其它

pku 3264Balanced Lineup

2010-01-24 11:07 113 查看
题目意思是:给你一组数,在给你一个范围,要你求这个范围里最大值与最小值的差。

思路:用线段树做,节点保存线段的左右端点,最大值和最小值。

/*
* File: main.cpp
* Author: Administrator
*
* Created on 2010年1月23日, 下午4:02
*/

#include <stdlib.h>
#include <iostream>
using namespace std;
#define N 50005

struct node {
int l, r;
int _max, _min;
} Tree[N * 3];
int a
;

int Max(int a, int b) {
if (a >= b)return a;
else return b;
}

int Min(int a, int b) {
if (a <= b)return a;
else return b;
}

void Build_Tree(int l, int r, int k) {
Tree[k].l = l;
Tree[k].r = r;
if (l == r) {
Tree[k]._max = a[l];
Tree[k]._min = a[l];
return;
}
int mid = (l + r) / 2;
Build_Tree(l, mid, 2 * k);
Build_Tree(mid + 1, r, 2 * k + 1);
Tree[k]._max = Max(Tree[2 * k]._max, Tree[2 * k + 1]._max);
Tree[k]._min = Min(Tree[2 * k]._min, Tree[2 * k + 1]._min);
}

int Find_max(int l, int r, int k) {
if (Tree[k].l == l && Tree[k].r == r) {
return Tree[k]._max;
}
int mid = (Tree[k].l + Tree[k].r) / 2;
if (r <= mid)return Find_max(l, r, 2 * k);
else if (l > mid)return Find_max(l, r, 2 * k + 1);
else {
int a, b;
a = Find_max(l, mid, 2 * k);
b = Find_max(mid + 1, r, 2 * k + 1);
return Max(a, b);
}
}

int Find_min(int l, int r, int k) {
if (Tree[k].l == l && Tree[k].r == r) {
return Tree[k]._min;
}
int mid = (Tree[k].l + Tree[k].r) / 2;
if (r <= mid)return Find_min(l, r, 2 * k);
else if (l > mid)return Find_min(l, r, 2 * k + 1);
else {
int a, b;
a = Find_min(l, mid, 2 * k);
b = Find_min(mid + 1, r, 2 * k + 1);
return Min(a, b);
}
}

/*
*
*/
int main(int argc, char** argv) {
int n, q, i, j;
while (scanf("%d%d", &n, &q) != EOF) {
for (i = 1; i <= n; i++) {
//cin>>a[i];
scanf("%d", &a[i]);
}
Build_Tree(1, n, 1);

while (q--) {
scanf("%d%d", &i, &j);//system("pause");
int ma = Find_max(i, j, 1);
int mb = Find_min(i, j, 1);
cout << ma - mb << endl;
}
}

return (EXIT_SUCCESS);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: