`

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

阅读更多
/* 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 ;
}

0
8
分享到:
评论

相关推荐

    线段树练习POJ 3264

    线段树是一种数据结构,常用于处理区间查询与更新的问题,它能高效地支持动态维护区间最值、求和等问题。在本题“POJ 3264”中,我们可能面临的是一个区间最值或者区间求和的计算任务。线段树的基本思想是将数组或...

    POJ3274-Gold Balanced Lineup

    【标题】"POJ3274-Gold Balanced Lineup" 是一道来自北京大学在线判题系统POJ(Problem Online Judge)的编程竞赛题目。这道题目的主要目标是通过编写程序来解决一个与数学和算法相关的问题。 【描述】"北大POJ3274...

    ACM常用算法及其相应的练习题.docx

    ACM常用算法及其相应的练习题 ... + poj3264, poj3368 * 并查集的高级应用 + poj1703, poj2492 * KMP算法 + poj1961, poj2406 四、搜索 * 最优化剪枝和可行性剪枝 * 搜索的技巧和优化 + poj3411, poj1724

    线段树入门学习(二)(兼解POJ3468) JAVA

    在本教程中,我们将深入探讨线段树的基本概念,以及如何使用Java实现线段树来解决实际问题,如POJ3468题目。 首先,理解线段树的核心在于它的分治思想。线段树将一个大区间(通常是一维数组)分成多个小区间,每个...

    POJ3277.rar_3277 poj_poj3277_多个面积_线段树

    标题中的“POJ3277.rar_3277 poj_poj3277_多个面积_线段树”是指一个与编程竞赛相关的压缩文件,特别提到了POJ(Problemset Online Judge)的第3277号问题。POJ是一个著名的在线编程竞赛平台,参与者需要解决各种...

    线段树入门学习(三)懒操作(兼解POJ1823) JAVA

    在本篇博文中,我们将深入探讨线段树的概念,以及如何实现懒惰更新(Lazy Propagation)策略,同时结合POJ1823问题进行实战应用。懒惰更新是优化线段树性能的关键技巧,它避免了频繁地对每个节点进行更新,从而减少...

    poj 2352 stars(树状数组,线段树)

    ### POJ 2352 Stars - 树状数组与线段树实现 #### 题目背景 POJ 2352 Stars 是一道经典的算法题目,它提供了使用树状数组或线段树来解决的可能性。这两种数据结构都是为了高效处理区间查询问题而设计的。在这篇...

    POJ1159-Palindrome

    【标题】"POJ1159-Palindrome" 是北京大学在线编程平台POJ上的一道编程题目。这道题目主要考察的是字符串处理和回文判断的知识点。 【描述】"北大POJ1159-Palindrome 解题报告+AC代码" 暗示了解决这道问题的方法和...

    图的深搜+树状数组练习 POJ 3321(JAVA)

    标题中的“图的深搜+树状数组练习 POJ 3321(JAVA)”指的是一个编程题目,其中涉及到图的深度优先搜索(DFS, Depth First Search)算法和树状数组(也称为线段树,Segment Tree)的数据结构。这个题目来源于POJ...

    POJ2528-Mayor's posters【区间映射压缩(离散化)+线段树】

    POJ2528-Mayor's posters 【区间映射压缩(离散化)+线段树】 解题报告+AC代码 http://hi.csdn.net/!s/83XZJU ========&gt; 我的所有POJ解题报告链接: http://blog.csdn.net/lyy289065406/article/details/6642573

    poj2823.cpp.tar.gz_线段树

    在`poj2823.cpp`源代码中,我们可以看到实现线段树的具体细节,包括如何初始化、更新以及查询线段树。此外,代码可能还包括了问题的输入输出处理,错误检查,以及可能的优化策略,比如lazy propagation(惰性传播)...

    北大POJ部分题目答案(一些基础题目)

    很多的POJ题目答案!1000~1008,1011~1014,1016,1017,1019,1028,1032,1045,1046,1047,1050,1061,1067,1068,1088,1102,1159,1163,1183,1207,1218,1226,1247,1256,1258,1298,1316,1323,...

    北大acm题解(poj题目分析)

    《北大ACM题解》是一本专为解决POJ(Programming Online Judge)平台上的编程竞赛题目而编写的指导书籍。ACM(国际大学生程序设计竞赛,International Collegiate Programming Contest)是一项全球性的比赛,旨在...

    北大POJ经典结题报告

    《北大POJ经典结题报告》是一份针对北京大学在线编程平台POJ的解题报告,旨在帮助学习者掌握算法和编程技巧,提升解决问题的能力。POJ(Problem Online Judge)是北大的一个在线编程竞赛系统,提供了丰富的算法题目...

    北大POJ 大量解题代码

    【标题】"北大POJ大量解题代码"指的是北京大学在线编程平台POJ上的一系列算法题目解决方案的集合。这些代码通常由ACM(国际大学生程序设计竞赛)参赛者或爱好者编写,旨在帮助学习者理解并解决各类算法问题,提高...

    北大poj解题报告

    北京大学在线编程平台POJ(PKU Online Judge)是许多学习算法和进行编程训练的学生们的重要实践场所。这个“北大poj解题报告”包含了作者在使用POJ平台解题过程中的学习总结和经验分享,旨在帮助软件工程专业的学生...

    北京大学poj题目类型分类

    北京大学POJ题目类型分类 北京大学POJ题目类型分类是根据题目的难易程度、知识领域和解决方法对POJ题目进行分类的。通过对POJ题目的分类,可以帮助学习者更好地理解和掌握算法和数据结构的知识。 简单题 简单题是...

    ACMer需要掌握的算法讲解 (2).docx

    * POJ3109、POJ1478、POJ1462、POJ2729、POJ2048、POJ3336、POJ3315、POJ2148、POJ1263 八、附录 * ACM算法列表 + 哈希表、哈希数组 + 堆、优先队列 + 双端队列可并堆左偏堆 + Treap伸展树并查集 + 集合计数...

    北大POJ初级-所有题目AC代码+解题报告

    北京大学(Peking University, 简称PKU)的POJ(Peking University Online Judge)是一个为计算机科学爱好者和学生提供在线编程训练的平台。这个资源集合了北大POJ初级阶段的所有题目,包含已通过(Accepted, AC)的...

Global site tag (gtag.js) - Google Analytics