ACM 数据结构 线段数 HDU 1754 I Hate It

原创 2016年05月31日 13:54:42
  1. 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
    Hint
    Huge input,the C function scanf() will work better than cin
     

    Author
    linle


  2. #include <stdio.h>  
  3. #include <conio.h>  
  4. #include <string.h>  
  5.   
  6. #define max(x1, y1) ((x1) > (y1) ? (x1) : (y1))  
  7. #define min(x1, y1) ((x1) < (y1) ? (x1) : (y1))  
  8.   
  9. #define MAXSIZE 200002  
  10.   
  11. typedef struct {  
  12.     int max ;  
  13.     int left, right ;  
  14. } NODE ;  
  15.   
  16. int     n, m ;  
  17. int     num [MAXSIZE] ;  
  18. NODE    tree[MAXSIZE * 20] ;  
  19.   
  20. // 构建线段树  
  21. int build (int root, int left, int right)  
  22. {  
  23.     int mid ;  
  24.   
  25.     // 当前节点所表示的区间  
  26.     tree[root].left     = left ;  
  27.     tree[root].right    = right ;  
  28.   
  29.     // 左右区间相同,则此节点为叶子,max 应储存对应某个学生的值  
  30.     if (left == right)  
  31.     {  
  32.         return tree[root].max = num[left] ;  
  33.     }  
  34.     mid = (left + right) / 2 ;  
  35.   
  36.     // 递归建立左右子树,并从子树中获得最大值  
  37.     int a, b ;  
  38.     a = build (2 * root, left, mid) ;  
  39.     b = build (2 * root + 1, mid + 1, right) ;  
  40.   
  41.     return tree[root].max = max (a, b) ;  
  42. }  
  43.   
  44. // 从节点 root 开始,查找 left 和 right 之间的最大值  
  45. int find (int root, int left, int right)  
  46. {  
  47.     int mid ;  
  48.     // 若此区间与 root 所管理的区间无交集  
  49.     if (tree[root].left > right || tree[root].right < left)  
  50.         return 0 ;  
  51.     // 若此区间包含 root 所管理的区间  
  52.     if (left <= tree[root].left && tree[root].right <= right)  
  53.         return tree[root].max ;  
  54.   
  55.     // 若此区间与 root 所管理的区间部分相交  
  56.   
  57.     int a, b ;  // 不能这样 max (find(...), find(...));  
  58.     a = find (2 * root, left, right) ;  
  59.     b = find (2 * root + 1, left, right) ;  
  60.   
  61.     return max (a, b) ;  
  62. }  
  63.   
  64. // 更新 pos 点的值  
  65. int update (int root, int pos, int val)  
  66. {  
  67.     // 若 pos 不存在于 root 所管理的区间内  
  68.     if (pos < tree[root].left || tree[root].right < pos)  
  69.         return tree[root].max ;  
  70.   
  71.     // 若 root 正好是一个符合条件的叶子  
  72.     if (tree[root].left == pos && tree[root].right == pos)  
  73.         return tree[root].max = val ;  
  74.   
  75.     // 否则。。。。  
  76.   
  77.     int a, b ;  // 不能这样 max (find(...), find(...));  
  78.     a = update (2 * root, pos, val) ;  
  79.     b = update (2 * root + 1, pos, val) ;  
  80.   
  81.     tree[root].max = max (a, b) ;  
  82.   
  83.     return tree[root].max ;  
  84. }  
  85.   
  86. int main ()  
  87. {  
  88.     char c ;  
  89.     int i ;  
  90.     int x, y ;  
  91.     while (scanf ("%d%d", &n, &m) != EOF)  
  92.     {  
  93.         for (i = 1 ; i <= n ; ++i)  
  94.             scanf ("%d", &num[i]) ;  
  95.         build (1, 1, n) ;  
  96.   
  97.         for (i = 1 ; i <= m ; ++i)  
  98.         {  
  99.             getchar () ;  
  100.             scanf ("%c%d%d", &c, &x, &y) ;  
  101.             if (c == 'Q')  
  102.             {  
  103.                 printf ("%d\n", find (1, x, y)) ;  
  104.             }  
  105.             else  
  106.             {  
  107.                 num[x] = y ;  
  108.                 update (1, x, y) ;  
  109.             }  
  110.         }  
  111.     }  
  112.     return 0 ;  
  113. }  
版权声明:本文为博主原创文章,未经博主允许不得转载。

[ACM] hdu 1754 I Hate It (线段树,单点更新)

I Hate It Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...
  • sr19930829
  • sr19930829
  • 2014年04月16日 19:21
  • 1449

hdu 1754 I Hate It(树状数组 | 线段树)

题目链接:hdu 1754 I Hate It 题目大意:略。 解题思路: 方法一:树状数组,注意查询的时候,如果为一个的时候要与当前的数进行比较。 #include #include ...
  • u011328934
  • u011328934
  • 2014年01月28日 19:31
  • 1011

HDU 1754 I Hate It (线段树 & 树状数组)

I Hate It Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Sub...
  • u013446688
  • u013446688
  • 2014年10月06日 01:30
  • 1284

数据结构_线段树_例题_ I Hate It(HDU 1754)

运用合理的数据结构可以优化程序。
  • LonerIt
  • LonerIt
  • 2015年08月11日 16:27
  • 217

数据结构 线段树 HDU 1754I Hate It(单点更新)

题意:给n门课,m次询问。 Q,a,b为询问,[a,b] ;’ U,a,b为更新第a个点,更新为b 题解:单点更新,线段树 #include #include #include #include...
  • DouBoomFly
  • DouBoomFly
  • 2016年08月16日 23:59
  • 105

HDU—1754—I_Hate_It—【数据结构】【线段树】【单点更新】

I Hate It Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tota...
  • u013795055
  • u013795055
  • 2015年02月13日 10:02
  • 250

ACM 粗心永远AC不了系列——HDU 1754 I Hate It|线段树区间求最值

线段树应用水题之一 一:线段树基本概念 1:概述 线段树,类似区间树,是一个完全二叉树,它在各个节点保存一条线段(数组中的一段子数组),主要用于高效解决连续区间的动态查询问题,由于二叉结...
  • The_sam
  • The_sam
  • 2017年04月29日 13:30
  • 260

HDU 1754 I Hate It【线段树,区间最值,单点更新,结构体】

线段树区间最值入门题,之前用线段树写过,今天结构体数组来一发。 原来线段树链接:http://blog.csdn.net/hurmishine/article/details/51959662 有个...
  • hurmishine
  • hurmishine
  • 2017年01月06日 22:30
  • 279

HDU 1754 I hate it 【线段树--单点更新,区间最值】

链接:click here~~  题意: 很多学校流行一种比较的习惯。老师们很喜欢询问,从某某到某某当中,分数最高的是多少。 这让很多学生很反感。 不管你喜不喜欢,现在需要你做的是,就是按照老...
  • u013050857
  • u013050857
  • 2015年03月25日 17:15
  • 613

HDU 1754——I Hate It(线段树单点修改)

基础模板题 #include #include #include #include #define M 200001 #define ls(x) x
  • u014141559
  • u014141559
  • 2014年08月03日 15:30
  • 459
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:ACM 数据结构 线段数 HDU 1754 I Hate It
举报原因:
原因补充:

(最多只允许输入30个字)