`

【哥种的第一棵线段树,至于你信不信,我反正信了】HDU 1754 I Hate It

阅读更多
http://acm.hdu.edu.cn/showproblem.php?pid=1754


Problem Description
很多学校流行一种比较的习惯。老师们很喜欢询问,从某某到某某当中,分数最高的是多少。
这让很多学生很反感。

不管你喜不喜欢,现在需要你做的是,就是按照老师的要求,写一个程序,模拟老师的询问。当然,老师有时候需要更新某位同学的成绩。

Input
本题目包含多组测试,请处理到文件结束。
在每个测试的第一行,有两个正整数 N 和 M ( 0<N<=200000,0<M<5000 ),分别代表学生的数目和操作的数目。
学生ID编号分别从1编到N。
第二行包含N个整数,代表这N个学生的初始成绩,其中第i个数代表ID为i的学生的成绩。
接下来有M行。每一行有一个字符 C (只取'Q'或'U') ,和两个正整数A,B。
当C为'Q'的时候,表示这是一条询问操作,它询问ID从A到B(包括A,B)的学生当中,成绩最高的是多少。
当C为'U'的时候,表示这是一条更新操作,要求把ID为A的学生的成绩更改为B。


Output
对于每一次询问操作,在一行里面输出最高成绩。

Sample Input
5 6
1 2 3 4 5
Q 1 5
U 3 6
Q 3 4
Q 4 5
U 2 9
Q 1 5


Sample Output
5
6
5
9


效率不错,用加速输入外挂快了2百多ms!!

至于你信不信,我反正信了!!


#include <iostream>
#include <fstream>
#include <algorithm>
#include <string>
#include <set>
//#include <map>
#include <queue>
#include <utility>
#include <iomanip>
#include <stack>
#include <list>
#include <vector>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
//#include <ctime>
#include <ctype.h>
using namespace std;
#define eps 1e-8
#define PI 3.14159265358979
#define inf 0x3fffffff

struct node{
	int l, r, maxs;    //一个结点表示一个区间[l, r]和区间的最大值maxs
}N[600005];
int v[200005];

inline int maxs (int a, int b)    //木有inline会慢一点点
{
	return a > b ? a : b;
}

void create (int u, int l, int r)    //创建线段树,设u为父结点
{
	N[u].l = l, N[u].r = r;
	if (l == r)
	{
		N[u].maxs = v[l];    //初始化子叶结点
		return ;
	}
	int mid = (l + r) >> 1;    //一个区间分为2个,变成左子树和右子树
	create (u+u, l, mid);    //递归建立左子树
	create (u+u+1, mid+1, r);    //递归建立右子树
	N[u].maxs = maxs (N[u+u].maxs, N[u+u+1].maxs);    //返回更新父亲结点的最大值
}

void update (int u, int id, int New)    //更新结点的值,id是结点编号,New是新的值
{
	if (N[u].l == N[u].r)
	{
		N[u].maxs = New;
		return ;
	}
	if (id <= N[u+u].r)    //id在左子树上【N[u+u]是N[u]的左子结点】
		update (u+u, id, New);    //继续递归寻找id
	else update (u+u+1, id, New);  //id在右子树上【N[u+u+1]是N[u]的右子结点】
	N[u].maxs = maxs (N[u+u].maxs, N[u+u+1].maxs);    //递归更新父亲结点的最大值
}

int find (int u, int start, int end)    //寻找[start,end]这个区间的最大值
{    //此函数博大精深,至于你信不信,我反正信了……
	if (start <= N[u].l && end >= N[u].r)
		return N[u].maxs;
	int m1 = -inf, m2 = -inf;
	if (start <= N[u+u].r)
		m1 = find (u+u, start, end);
	if (end >= N[u+u+1].l)
		m2 = find (u+u+1, start, end);
	return maxs (m1, m2);
}

inline bool scan_d(int &num)      // 加速输入外挂,纯粹复制模板
{
        char in;
        bool IsN=false;
        in=getchar();
        if(in==EOF) return false;
        while(in!='-'&&(in<'0'||in>'9')) in=getchar();
        if(in=='-'){ IsN=true;num=0;}
        else num=in-'0';
        while(in=getchar(),in>='0'&&in<='9'){
                num*=10,num+=in-'0';
        }
        if(IsN) num=-num;
        return true;
}

int main()
{
	int n, m, i, a, b;
	char ch[3];
	while (~scanf ("%d%d", &n, &m))
	{
		for (i = 1; i <= n; i++)
			scan_d (v[i]);    //加速输入
		create (1, 1, n);    //创建并初始化线段树,1是根结点
		while (m--)
		{
			//scanf ("%s%d%d", ch, &a, &b);
			scanf ("%s", ch);
			scan_d (a);    //加速输入
			scan_d (b);
			if (ch[0] == 'Q')    //寻找[a,b]区间的最大值
				printf ("%d\n", find (1, a, b));
			else update (1, a, b);    //更新结点的值
		}
	}
    return 0;
}
  • 大小: 7.1 KB
2
8
分享到:
评论

相关推荐

    线段树入门学习(兼解HDU1754)

    线段树是一种数据结构,主要用于高效地处理区间查询与修改问题。在计算机科学中,它在动态规划、算法竞赛等领域有着广泛的应用。这篇博客“线段树入门学习(兼解HDU1754)”旨在帮助初学者理解线段树的基本概念,并...

    hdu acm1166线段树

    hdu 1166线段树代码

    hdu 1166线段树

    标题与描述均提到了“hdu 1166线段树”,这表明文章的核心是关于线段树在解决特定问题中的应用。线段树是一种数据结构,主要用于处理区间查询和更新操作,尤其是在大规模数据集上。在本例中,通过分析给定的部分代码...

    ACM hdu 线段树题目+源代码

    New 操作时,我们可以从左到右遍历线段树,找到第一个可用的内存单元,分配该单元并更新其懒惰标记。Free 操作时,我们可以找到该内存单元,并将其懒惰标记设置为 0。Get 操作时,我们可以遍历线段树,找到第 x 个...

    线段树完整版

    线段树是一种二叉树数据结构,常用于处理区间查询或区间更新的问题。它将一个线性序列分割成多个不连续的段,每一个节点代表一个区间,并且通过递归的方式将这些区间进一步分割为更小的子区间,直到每个叶子节点代表...

    HH神总结的线段树专辑-超经典的

    本文作者提到,在早期撰写的一篇关于线段树的文章中,虽然得到了较高的阅读量,但随着时间的推移和技术的进步,作者对于自己早期的代码风格感到不满意,并认为其不够优雅。因此,作者决定重新编写相关内容并分享最新...

    线段树题目

    在构建线段树时,需要考虑如何根据第一个元素移动到最后一个元素时逆序数的变化规律来进行更新。 - **POJ 2828** 和 **POJ 2180**:这两道题都需要从后往前推进,线段树用于存储空位数量,以便快速查找空位的位置。...

    hdu 3333 turing tree 解题报告

    对于每个区间,从`bi+1`开始插入,直到`b(i+1)`,每次插入都会更新线段树中对应区间的`value`。 5. 插入完成后,可以通过查询线段树得到每个区间 `[ai, bi]` 内不同数字的和。 **时间复杂度分析**: - 每个数字...

    HDU 1022 Train Problem I 附详细思路

    HDU 1022 Train Problem I 附详细思路

    线段树入门

    线段树入门资料,有利于初学者学习,让他们详细了解线段树。

    hdu 300+ AC 代码

    2. **线段树**:线段树是一种数据结构,用于高效地处理区间查询和更新操作。它可以实时维护一个区间内的信息,如求和、最大值或最小值。线段树在处理动态区间问题时非常有效,如在数组上进行区间加法、区间求和等...

    hdu.rar_hdu

    HDU(杭州电子科技大学在线评测系统)是一个深受程序员喜爱的在线编程练习平台,它提供了丰富的算法题目供用户挑战,帮助他们提升编程技能和算法理解能力。"hdu.rar_hdu"这个压缩包文件很可能是某位程序员整理的他在...

    二叉搜索树练习 HDU3791

    **二叉搜索树(Binary Search Tree,BST)**是一种特殊的二叉树结构,它具有以下特性: 1. **性质**:对于任意节点,其左子树中的所有节点的值都小于该节点的值,右子树中的所有节点的值都大于该节点的值。 2. **...

    HDU题目java实现

    【标题】"HDU题目java实现"所涉及的知识点主要集中在使用Java编程语言解决杭州电子科技大学(HDU)在线评测系统中的算法问题。HDU是一个知名的在线编程竞赛平台,它提供了大量的算法题目供参赛者练习和提交解决方案...

    hdu动态规划算法集锦

    - 状态转移方程:$f[j] = \max\{f[j], f[j - q[i].money] + q[i].v\}$,其中$q[i].money$是第$i$个地点的价值,$q[i].v$是第$i$个地点的花费。 - 初始条件:$f[0] = 1$(不抢劫任何地方的情况)。 #### 3A:100A:...

    【hdu5306】Gorgeous Sequence 线段树区间最值操作-附件资源

    【hdu5306】Gorgeous Sequence 线段树区间最值操作-附件资源

    HDU DP动态规划

    【标题】"HDU DP动态规划"涉及到的是在算法领域中的动态规划(Dynamic Programming,简称DP)技术,这是解决复杂问题的一种高效方法,尤其适用于有重叠子问题和最优子结构的问题。动态规划通常用于优化多阶段决策...

    解题代码 hdu1241

    DFS是一种用于遍历或搜索树或图的算法。在这个过程中,算法从根节点开始探索尽可能深的子节点路径。当到达最深的叶子节点时,它会回溯到最近的一个未完成探索的节点,并继续进行探索。 **实现方法:** DFS通常有两...

    HDU_2010.rar_hdu 2010_hdu 20_hdu acm20

    【标题】"HDU_2010.rar"是一个压缩包文件,其中包含了与"HDU 2010"相关的资源,特别是针对"HDU ACM20"比赛的编程题目。"hdu 2010"和"hdu 20"可能是该比赛的不同简称或分类,而"hdu acm20"可能指的是该赛事的第20届...

    hdu 1257 最低拦截系统 lis

    这里所谓的“最低拦截系统”可能是为了形象地表达在一系列数值中找到一个递增序列的过程,可以想象成一系列高度不一的障碍物,我们需要找到一种方式能够连续地越过这些障碍物。 ### 解题思路 #### 1. 理解最长递增...

Global site tag (gtag.js) - Google Analytics