关闭

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

182人阅读 评论(0) 收藏 举报
分类:
  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. }  
0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:37568次
    • 积分:2129
    • 等级:
    • 排名:第17856名
    • 原创:183篇
    • 转载:2篇
    • 译文:0篇
    • 评论:8条
    文章分类