线段树入门变种

版权声明:本文由作者原创,如需使用请联系作者,侵权必究 https://blog.csdn.net/Elliot_Alderson/article/details/84194923

       至于线段树,emmm。。。借用温姐的博客,上次她给我们讲的时候用的就是自己的博客:温姑娘算法精讲:线段树

       学姐都已经工作了,再看看我这个辣鸡....哎....

       那么这次就是我这个辣鸡给大家更新一个线段树最简单的入门变种题目。

       没错,万恶的杭电(滑稽)的题目,杭电题目:Balanced Lineup,线段树的简单入门变种,至于线段树,翻上面学姐的博客,讲的非常清楚,简单。

       本题题意:让你找出给出的n个数字的指定区间当中的最大数字差值。

       嗯,题目扯了一大堆其实就这么一句话。

       这题其实就是线段树,大佬应该一眼就可以看出来的样子,然后不是维护节点一个最值,而是维护两个。坑点就在这,因为是两个,所以你需要通知保存最大最小值的信息,所以查询函数不能直接返回其差值,不然答案会出错,如果用的是结构体的话就要考虑考虑再写一个变量存这些信息了。

       emmm...其余的坑点...貌似没了吧?更新函数的话也注意一下,因为是更新最值,而且是两个。

       扯了这么多,代码就是这样啦~

#include<stdio.h>
#define max 50010

int num[max];

struct Node//节点结构体
{
	int left, right;
	int highest, lowest;
}node[max << 2], temp;


void push_Up(int root)//单点更新函数
{
	node[root].highest = node[root << 1].highest >= node[root << 1 | 1].highest ? node[root << 1].highest : node[root << 1 | 1].highest;
	node[root].lowest = node[root << 1].lowest <= node[root << 1 | 1].lowest ? node[root << 1].lowest : node[root << 1 | 1].lowest;
}


void build_Tree(int root, int left, int right)//种树函数
{
	node[root].left = left;
	node[root].right = right;
	if (left == right)
	{
		node[root].highest = node[root].lowest = num[left];
		return;
	}
	int mid = (left + right) >> 1;
	build_Tree(root << 1, left, mid);
	build_Tree(root << 1 | 1, mid + 1, right);
	push_Up(root);
}


void question(int l, int r, int root, int left, int right)//查询函数
{
	if (l == left && r == right)
	{
		temp.highest = temp.highest >= node[root].highest ? temp.highest : node[root].highest;
		temp.lowest = temp.lowest <= node[root].lowest ? temp.lowest : node[root].lowest;
		return;
	}
	int mid = (left + right) >> 1;
	if (mid >= l && mid < r)
	{
		question(l, mid, root << 1, left, mid);
		question(mid + 1, r, root << 1 | 1, mid + 1, right);
		return;
	}
	else if (mid >= r)
	{
		question(l, r, root << 1, left, mid);
		return;
	}
	else if (mid < l)
	{
		question(l, r, root << 1 | 1, mid + 1, right);
		return;
	}
}

int main()
{
	int n, m;
	scanf("%d%d", &n, &m);
	for (int i = 1; i < n + 1; i++)
	{
		scanf("%d", &num[i]);
	}
	build_Tree(1, 1, n);

	int a, b;
	for (int i = 0; i < m; i++)
	{
		scanf("%d%d", &a, &b);
		temp.highest = 0;//这里注意每次查询结果用temp保存,所以temp需要初始化,下同
		temp.lowest = 1000010;
		question(a, b, 1, 1, n);
		printf("%d\n", temp.highest - temp.lowest);
	}
	return 0;
}

       喜欢的朋友记得关注分享一条龙服务啊~

猜你喜欢

转载自blog.csdn.net/Elliot_Alderson/article/details/84194923