• HDU-1754 I Hate It(线段树单点更新,维护区间最大值)


    题目描述

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

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

    输入格式

    本题目包含多组测试,请处理到文件结束

    在每个测试的第一行,有两个正整数 N N N M ( 0 < N ≤ 200000 , 0 < M < 5000 ) M ( 0M(0<N200000,0<M<5000),分别代表学生的数目和操作的数目。

    学生 ID 编号分别从 1 1 1 编到 N N N

    第二行包含 N N N 个整数,代表这 N N N 个学生的初始成绩,其中第 i i i 个数代表 ID 为 i i i 的学生的成绩。

    接下来有 M M M 行。每一行有一个字符 C C C (只取 ′ Q ′ 'Q' Q ′ U ′ 'U' U ) ,和两个正整数 A A A B B B

    C C C ′ Q ′ 'Q' Q 的时候,表示这是一条询问操作,它询问 ID 从 A A A B B B (包括 A , B A,B A,B)的学生当中,成绩最高的是多少。

    C C C ′ U ′ 'U' U 的时候,表示这是一条更新操作,要求把 ID 为 A A A 的学生的成绩更改为 B B B

    输出格式

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

    样例输入

    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    样例输出

    5
    6
    5
    9
    
    • 1
    • 2
    • 3
    • 4

    提交链接

    https://acm.hdu.edu.cn/showproblem.php?pid=1754

    提示

    大量输入,scanf() 将比 cin 更好地工作。

    样例解释:
    5 个数分别为 1 2 3 4 5,6 次询问。
    Q 1 5,询问区间 [1,5] 的最大值,输出的结果为 5。
    U 3 6 ,将 id 为 3 的学生的成绩改为 6,改完之后的 5 个数为 1 2 6 4 5
    Q 3 4,询问区间 [3,4] 的最大值,输出的结果为 6。
    Q 4 5,询问区间 [4,5] 的最大值,输出的结果为 5。
    U 2 9,将 id 为 2 的学生的成绩改为 9,改完之后的 5 个数为 1 9 6 4 5
    Q 1 5,询问区间 [1,5] 的最大值,输出的结果为 9。

    解析

    单点更新,不需要懒惰标记。
    建树,更新操作,询问操作。

    参考代码

    #include
    #include
    #include
    using namespace std;
    const int maxn = 8e5 + 9;
    int mx[maxn << 2] , a[maxn];
    int n , m;
    void build(int l , int r , int k)
    {
    	if(l == r)   //叶子结点
    	{
    		mx[k] = a[l];
    		return;
    	}
    	int mid = (l + r) >> 1; 
    	build(l , mid , k << 1);  //左子树 
    	build(mid + 1 , r , k << 1 | 1);  //右子树 
    	mx[k] = max(mx[k << 1] , mx[k << 1 | 1]);
    }
    void update(int pos , int target , int l , int r , int k)
    {
    	if(l == r)
    	{
    		mx[k] = target;
    		return;
    	}
    	int mid = (l + r) >> 1;
    	if(pos <= mid)
    		update(pos , target , l , mid , k << 1);
    	else
    		update(pos ,  target , mid + 1 , r ,  k << 1 | 1);
    	mx[k] =  max(mx[k << 1] , mx[k << 1 | 1]);
    } 
    int  query(int x , int y , int l , int r , int k)
    {
    	if(x <= l && y >= r) // x l r y 
    		return mx[k];
    	int mid = (l  + r) >> 1;
    	if(y <= mid)
    		return query(x , y , l , mid , k << 1);
    	if(x > mid)
    		return query(x , y , mid + 1 , r , k << 1 | 1);
    	return max(query(x , y , l , mid , k << 1) , query(x , y , mid + 1 , r , k << 1 | 1));
    }
    int main()
    {
    	while(~scanf("%d%d" , &n , &m))
    	{
    		memset(mx , 0 , sizeof(mx));
    		for(int i = 1; i <= n; i++)
    			scanf("%d" , &a[i]);
    		build(1 , n , 1);  //建树
    		char op[2];
    		int a , b;
    		while(m--)
    		{
    			scanf("%s%d%d",op , &a , &b);
    			if(op[0] == 'Q')
    				printf("%d\n" , query(a , b , 1 , n , 1));   //询问 [a,b] 之间的最大值
    			else
    				update(a , b , 1 , n , 1);     //id 为 a 的学生的成绩改为 b 
    		}
    	}
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
  • 相关阅读:
    websocket与Socket的区别
    RocketMQ回顾整理
    Sentinel使用Nacos存储规则——Gateway网关服务
    优先级队列的使用及模拟实现
    全栈开发笔记2:项目部署上线的三种方式
    Python实时采集Windows CPU\MEMORY\HDD使用率
    Freertos学习第三天-ESP32基于Freertos任务共享全局变量
    文字转语音朗读如何操作?手把手教你如何将文字转语音
    Notebook系列第11期:基于POT工具API模式的模型量化方法
    渐变圆角边框css
  • 原文地址:https://blog.csdn.net/lylzsx20172018/article/details/133943158