【线段树 + 详细注释】北大 poj 3264 Balanced Lineup

来源:互联网 发布:淘宝商家多发货 编辑:程序博客网 时间:2024/05/16 01:33
/* 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: 9381120panyanyany3264Accepted2208K1860MSC++2677B2011-10-01 19:56:56Test Data :Review :呃,修改了一下,提交,AC,很高兴,觉得这题其实也不太难嘛~~~,呃,然后,看了下“英雄哪里出来”大神的代码,立刻石化,代码如此少,如此简洁,运用如此巧妙,简直是我辈之模范啊。然后再看自己的代码,顿时没了兴趣,就好像一肥婆相比于苗条少女,真是自惭形愧啊~~~在此附上大神的地址:http://www.cppblog.com/menjitianya/archive/2011/03/29/142964.html人家把树的构建和更新整合在一起,大大减少的代码量,同时也根据线段树的特点,省去了结构体中的 left,和 right,节省了内存空间。实在是很巧妙。//----------------------------------------------------------------------------*/#include <stdio.h>#include <string.h>#define INF0x7f7f7f7f#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 {intlow, high ;intleft, right ;} NODE ;intn, q ;NODEtree[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 (){inti, 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 ;}

原创粉丝点击