/* THE PROGRAM IS MADE BY PYY */
/*----------------------------------------------------------------------------//
Copyright (c) 2011 panyanyany All rights reserved.
URL : http://poj.org/problem?id=3264
Name : 3264 Balanced Lineup
Date : Saturday, October 1, 2011
Time Stage : more than one hour
Result:
9381120 panyanyany
3264
Accepted 2208K 1860MS C++
2677B 2011-10-01 19:56:56
Test Data :
Review :
呃,修改了一下,提交,AC,很高兴,觉得这题其实也不太难嘛~~~,呃,然后,
看了下“英雄哪里出来”大神的代码,立刻石化,代码如此少,如此简洁,运用如此巧妙,
简直是我辈之模范啊。然后再看自己的代码,顿时没了兴趣,就好像一肥婆相比于苗条少女,
真是自惭形愧啊~~~
在此附上大神的地址:
http://www.cppblog.com/menjitianya/archive/2011/03/29/142964.html
人家把树的构建和更新整合在一起,大大减少的代码量,同时也根据线段树的特点,省去了
结构体中的 left,和 right,节省了内存空间。实在是很巧妙。
//----------------------------------------------------------------------------*/
#include <stdio.h>
#include <string.h>
#define INF 0x7f7f7f7f
#define MAXSIZE 50010
#define L(n) ((n) << 1)
#define R(n) (((n) << 1) + 1)
#define MID(a, b) (((a) + (b)) >> 1)
#define min(a, b) (((a) < (b)) ? (a) : (b))
#define max(a, b) (((a) > (b)) ? (a) : (b))
typedef struct {
int low, high ;
int left, right ;
} NODE ;
int n, q ;
NODE tree[MAXSIZE * 10] ;
void swap (int &lhs, int &rhs)
{
int tmp ;
tmp = lhs ;
lhs = rhs ;
rhs = tmp ;
}
void build (int node, int left, int right)
{
tree[node].left = left ;
tree[node].right = right ;
tree[node].low = INF ; // 初始化的时候赋值为无限大
tree[node].high = -INF ; // 初始化的时候赋值为无穷小
if (left == right)
return ;
int mid = MID (left, right) ;
build (L(node), left, mid) ;
build (R(node), mid + 1, right) ;
}
void update (int node, int left, int right, int pos, int x)
{
// 到达叶子
if (tree[node].left == tree[node].right && tree[node].left == pos)
{
tree[node].low = tree[node].high = x ;
return ;
}
int mid = MID (tree[node].left, tree[node].right) ;
// 当前最大值、最小值与新值进行比较,若有可能,则更新最大值 或 最小值
tree[node].low = min (tree[node].low, x) ;
tree[node].high = max (tree[node].high, x) ;
// 若该点在当前区间左半部
if (pos <= mid)
update (L(node), left, mid, pos, x) ;
// 若该点在右半区间
else if (mid < pos)
update (R(node), mid + 1, right, pos, x) ;
}
void query (int node, int left, int right, int *x, int *y)
{
// 查找区间正好是当前区间
// *x 为当前区间的最小值,*y 为当前区间的最大值
if (tree[node].left == left && tree[node].right == right)
{
*x = tree[node].low ;
*y = tree[node].high ;
return ;
}
int mid = MID (tree[node].left, tree[node].right) ;
int x1, y1, x2, y2 ;
// 若所查找区间在当前区间的左半部
if (right <= mid)
{
query (L(node), left, right, &x1, &y1) ;
*x = x1 ;
*y = y1 ;
}
// 若所查找区间在当前区间的右半部
else if (mid < left)
{
query (R(node), left, right, &x2, &y2) ;
*x = x2 ;
*y = y2 ;
}
// 若所查找区间 横跨 当前区间的中部
else
{
query (L(node), left, mid, &x1, &y1) ;
query (R(node), mid + 1, right, &x2, &y2) ;
*x = min (x1, x2) ;
*y = max (y1, y2) ;
}
return ;
}
int main ()
{
int i, j ;
int x, y, low, high ;
while (scanf ("%d%d", &n, &q) != EOF)
{
build (1, 1, n) ;
for (i = 1 ; i <= n ; ++i)
{
scanf ("%d", &x) ;
update (1, 1, i, i, x) ;
}
for (i = 1 ; i <= q ; ++i)
{
scanf ("%d%d", &x, &y) ;
if (x > y)
swap (x, y) ;
query (1, x, y, &low, &high) ;
printf ("%d\n", high - low) ;
}
}
return 0 ;
}
【线段树 + 详细注释】北大 poj 3264 Balanced Lineup
最新推荐文章于 2023-10-07 08:26:33 发布