zoukankan      html  css  js  c++  java
  • hdu 1754 I Hate It (线段树功能:单点更新和区间最值)

    版权声明:本文为博主原创文章。未经博主同意不得转载。vasttian https://blog.csdn.net/u012860063/article/details/32982923

    转载请注明出处:http://blog.csdn.net/u012860063

    题目链接: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


    代码例如以下:

    //线段树功能:update:单点替换 query:区间最值
    //此题为Hdu 1754
    
    #include <cstdio>
    #include <algorithm>
    using namespace std;
    #define lson l , mid , rt << 1
    #define rson mid + 1 , r , rt << 1 | 1
    //lson和rson分辨表示结点的左儿子和右儿子
    //rt表示当前子树的根(root),也就是当前所在的结点
    const int maxn = 222222;
    //maxn是题目给的最大区间,而节点数要开4倍,确切的来说节点数要开大于maxn的最小2x的两倍
    int sum[maxn<<2];
    int max(int x,int y)
    {
    	if(x > y)
    		return x;
    	return y;
    }
    void PushUP(int rt) //把当前结点的信息更新到父结点
    {
    	sum[rt] = max(sum[rt<<1],sum[rt<<1|1]);
    }
    
    void build(int l,int r,int rt)
    {
    	if (l == r)
    	{
    		scanf("%d",&sum[rt]);
    		return ;
    	}
    	int mid = (l + r) >> 1;
    	build(lson);
    	build(rson);
    	PushUP(rt);
    }
    void update(int p,int sc,int l,int r,int rt) 
    {
    	if (l == r) //叶节点
    	{
    		sum[rt] = sc;
    		return ;
    	}
    	int mid = (l + r) >> 1;
    	if (p <= mid)//递归更新左子树或者右子树
    		update(p , sc , lson);
    	else 
    		update(p , sc , rson);
    	PushUP(rt);
    }
    int query(int L,int R,int l,int r,int rt)
    {//查询区间[L,R]中的最大值
    	if (L <= l && r <= R)//当前结点全然包括在查询区间内
    	{
    		return sum[rt];
    	}//要取rt子节点的值时,也要先把rt的延迟标记向下移动
    	int mid = (l + r) >> 1;
    	int ret = 0;
    	if (L <= mid) //往左走
    		ret = max(ret,query(L , R , lson));
    	if (mid < R)//往右走
    		ret = max(ret,query(L , R , rson));
    	return ret;
    }
    int main() 
    {
    	int N , M;
    	while(~scanf("%d%d",&N,&M))//N为节点数
    	{
    		build(1 , N , 1); //建树
    		while (M--)//M为询问次数
    		{
    			char op[2];
    			int a , b;
    			scanf("%s%d%d",op,&a,&b);
    			if (op[0] == 'Q') 
    			{
    				printf("%d
    ",query(a , b , 1 , N , 1));
    			}
    			else
    			{
    				update(a , b , 1 , N , 1);//把a的成绩更为b
    			}
    		}
    	}
    	return 0;
    }


  • 相关阅读:
    multipart/form-data
    Java面试之SE基础基本数据类型
    数据库中的悲观锁和乐观锁详解
    j2SE基回顾(一)
    Hibernate 检索查询的几种方式(HQL,QBC,本地SQL,集成Spring等)
    消防(bzoj 2282)
    YY的GCD(bzoj 2820)
    Problem b(bzoj 2301)
    完全平方数(bzoj 2440)
    The Luckiest number(hdu 2462)
  • 原文地址:https://www.cnblogs.com/mqxnongmin/p/10727865.html
Copyright © 2011-2022 走看看