zoukankan      html  css  js  c++  java
  • I Hate It(线段树+更新)

     很多学校流行一种比较的习惯。老师们很喜欢询问,从某某到某某当中,分数最高的是多少。
     这让很多学生很反感。
     不管你喜不喜欢,现在需要你做的是,就是按照老师的要求,写一个程序,模拟老师的询问。当然,老师有时候需要更新某位同学的成绩。

    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

    题意:
     给一串数,操作能给任意数赋值,问区间内和

    思路:
     线段树,改动叶子节点的值后返回到上一层,向上更新

     1 #include <stdio.h>
     2 #include <string.h>
     3 
     4 struct node
     5 {
     6     int left, right, data;
     7 } tree[800005];
     8 int a[200005], re;
     9 
    10 int max(int x, int y)
    11 {
    12     if(x <= y) return y;
    13     else return x;
    14 }
    15 
    16 void creat(int l, int r, int k)
    17 {
    18     tree[k].left = l;
    19     tree[k].right = r;
    20     if(l==r)
    21     {
    22         tree[k].data = a[l];
    23         return;
    24     }
    25     else
    26     {
    27         creat(l, (l+r)/2, 2*k);
    28         creat((l+r)/2+1, r, 2*k+1);
    29         tree[k].data = max(tree[2*k+1].data, tree[2*k].data);
    30     }
    31 }
    32 
    33 int query(int l, int r, int k)
    34 {
    35     int mid = (tree[k].left+tree[k].right)/2;
    36     if(l <= tree[k].left && tree[k].right <= r) return tree[k].data;
    37               //之前写成if(tree[k].left==tree[k].right) return tree[k].data;
    38               //每次都递归到叶子,没发挥线段树的区间优势,很当然的超时了,
    39               //改元素值的时候才需要递归到叶子,看下面change
    40     else if(r <= mid) return query(l, r, 2*k);
    41     else if(l >= mid + 1) return query(l, r, 2*k+1);
    42     else return max(query(l, r, 2*k), query(l, r, 2*k+1));
    43 }
    44 
    45 void change(int x, int y, int k)
    46 {
    47     if(tree[k].left==tree[k].right)        //递归到叶子才能赋值,然后返回一层层往上更新各区间max
    48     {
    49         tree[k].data = y;
    50         return;
    51     }
    52     else
    53     {
    54         int mid = (tree[k].left+tree[k].right)/2;
    55         if(x<=mid) change(x, y, 2*k);
    56         else change(x, y, 2*k+1);
    57         tree[k].data = max(tree[2*k].data, tree[2*k+1].data);
    58     }
    59 }
    60 
    61 int main()
    62 {
    63     int i, n, m, x, y;
    64     char order;
    65     while(~scanf("%d %d", &n, &m))
    66     {
    67         for(i=1; i<=n; i++)
    68         {
    69             scanf("%d", &a[i]);
    70         }
    71         creat(1, n, 1);
    72         while(m--)
    73         {
    74             getchar();
    75             scanf("%c %d %d", &order, &x, &y);
    76             if(order=='Q') printf("%d
    ", query(x, y, 1));
    77             else
    78             {
    79                 a[x] = y;
    80                 change(x, y, 1);
    81             }
    82         }
    83     }
    84     return 0;
    85 }
  • 相关阅读:
    自制flash3D变换类
    Alchemy的使用和多项式批量计算的优化
    Bresenham直线扫描算法
    模拟流体粒子运动
    任意多边形的碰撞检测——向量积判断方法
    漂亮的雪花飘落和堆积效果
    发个简单怡情的粒子随机运动
    三次贝塞尔曲线绘制算法(优化过)
    失败是成功之母
    typeid操作符
  • 原文地址:https://www.cnblogs.com/0xiaoyu/p/11356300.html
Copyright © 2011-2022 走看看