I Hate It:线段树:单点修改+区间查询

I Hate It

Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 40034    Accepted Submission(s): 15898

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
 
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<string>
using namespace std;
const int MX = 200010;			//注意最大值	

struct node {
	int l, r, maxn,minn;
}tree[MX<<2];
int n, q, x, y;

void pushup(int p) {			//单点更新
	tree[p].maxn = max(tree[p << 1].maxn, tree[p << 1 | 1].maxn);
//	tree[p].minn = min(tree[p << 1].minn, tree[p << 1 | 1].minn);
}

void built(int p, int l, int r) {			//建树
	tree[p].l = l;
	tree[p].r = r;
	if (l == r) {
		scanf("%d", &tree[p].maxn);
	//	tree[p].minn = tree[p].maxn;
		return;
	}
	int mid = l + r >> 1;
	built(p << 1, l, mid);
	built(p << 1 | 1, mid + 1, r);
	pushup(p);
}

void update(int p, int a, int a1) {			//单点修改
	if (tree[p].l==tree[p].r) {
		tree[p].maxn = a1;
		return;
	}
	int mid = tree[p].l + tree[p].r >> 1;
	if (a <= mid)
		update(p << 1, a, a1);
	else 
		update(p << 1 | 1, a, a1);
	pushup(p);
}

int querymax(int p, int l, int r) {			//区间查询
	int res = 0;
	if (l <= tree[p].l&&tree[p].r <= r) {
		return tree[p].maxn;
	}

	int mid = tree[p].l + tree[p].r >> 1;
	if (l <= mid)res=max(res,querymax(p << 1, l, r));
	if (r > mid)res = max(res, querymax(p << 1 | 1, l, r));
	return res;
}

//int querymin(int p, int l, int r) {
//	int res = 9999999;
//	if (l <= tree[p].l&&tree[p].r <= r) {
//		return tree[p].minn;
//	}
//
//	int mid = tree[p].l + tree[p].r >> 1;
//	if (l <= mid)res = min(res, querymin(p << 1, l, r));
//	if (r > mid)res = min(res, querymin(p << 1 | 1, l, r));
//	return res;
//}

int main() {
	while (scanf("%d%d", &n, &q) != EOF) {
		built(1, 1, n);
		while (q--) {
			char s[2];
			scanf("%s%d%d", s, &x, &y);
			getchar();
			if (s[0] == 'Q')
				printf("%d\n", querymax(1, x, y));
			else
				update(1, x, y);
		}
	}
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
对于计算机专业的学生而言,参加各类比赛能够带来多方面的益处,具体包括但不限于以下几点: 技能提升: 参与比赛促使学生深入学习和掌握计算机领域的专业知识与技能,如编程语言、算法设计、软件工程、网络安全等。 比赛通常涉及实际问题的解决,有助于将理论知识应用于实践中,增强问题解决能力。 实践经验: 大多数比赛都要求参赛者设计并实现解决方案,这提供了宝贵的动手操作机会,有助于积累项目经验。 实践经验对于计算机专业的学生尤为重要,因为雇主往往更青睐有实际项目背景的候选人。 团队合作: 许多比赛鼓励团队协作,这有助于培养学生的团队精神、沟通技巧和领导能力。 团队合作还能促进学生之间的知识共享和思维碰撞,有助于形成更全面的解决方案。 职业发展: 获奖经历可以显著增强简历的吸引力,为求职或继续深造提供有力支持。 某些比赛可能直接与企业合作,提供实习、工作机会或奖学金,为学生的职业生涯打开更多门路。 网络拓展: 比赛是结识同行业人才的好机会,可以帮助学生建立行业联系,这对于未来的职业发展非常重要。 奖金与荣誉: 许多比赛提供奖金或奖品,这不仅能给予学生经济上的奖励,还能增强其成就感和自信心。 荣誉证书或奖状可以证明学生的成就,对个人品牌建设有积极作用。 创新与研究: 参加比赛可以激发学生的创新思维,推动科研项目的开展,有时甚至能促成学术论文的发表。 个人成长: 在准备和参加比赛的过程中,学生将面临压力与挑战,这有助于培养良好的心理素质和抗压能力。 自我挑战和克服困难的经历对个人成长有着深远的影响。 综上所述,参加计算机领域的比赛对于学生来说是一个全面发展的平台,不仅可以提升专业技能,还能增强团队协作、沟通、解决问题的能力,并为未来的职业生涯奠定坚实的基础。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

gy-7

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值