• HDU 1556 Color the ball 线段树


    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1556

    参考实验室大佬链接:http://www.cnblogs.com/baocong/p/6698872.html

    线段树区间更新模板题,还不是很熟练,晚上再写几道题。

    个人理解:点更新容易理解,而区间更新主要特殊点在于为了减小更新时的时间复杂度,它引入了延迟标记-lazy,这个标记目的是标记这个节点,来表示此节点包含的区间(也就是儿子们)被更新过。

    因此在进行更新以及查询操作的时候,需要先将当前节点的延迟标记(如果标记了的话)作用在它包含的区间也就是儿子们身上,也就是说将它的儿子更新。然后再继续对它的儿子们更新或者查询。

    代码:

     1 #define maxn 300010
     2 struct node{
     3     int l, r, v;
     4     int lazy;
     5     node() {}
     6     node(int ll, int rr, int vv, int la): l(ll), r(rr), v(vv), lazy(la) {}
     7 };
     8 int n, a[maxn];
     9 node tree[maxn];
    10 
    11 int buildTree(int l, int r, int nodenum){
    12     if(l == r){
    13         tree[nodenum] = node(l, r, a[l], 0);
    14         return a[l];
    15     }
    16     int mid = (l + r) >> 1;
    17     buildTree(l, mid, nodenum << 1);
    18     buildTree(mid + 1, r, nodenum << 1 | 1);
    19     tree[nodenum] = node(l, r, 0, 0);
    20     return 0;
    21 }
    22 void pushdown(int rt){
    23     if(tree[rt].lazy){
    24         tree[rt << 1].lazy += tree[rt].lazy;
    25         tree[rt << 1 | 1].lazy += tree[rt].lazy;
    26         tree[rt << 1].v += tree[rt].lazy;
    27         tree[rt << 1 | 1].v += tree[rt].lazy;
    28         tree[rt].lazy = 0;
    29     }
    30 }
    31 
    32 void update(int ql, int qr, int v, int l, int r, int nodenum){
    33     if(l == ql && r == qr){
    34         if(l == r) tree[nodenum].v += v;
    35         else tree[nodenum].lazy += v;
    36         return;
    37     }
    38     pushdown(nodenum);
    39     int mid = (l + r) >> 1;
    40     if(qr <= mid)
    41         update(ql, qr, v, l, mid, nodenum << 1);
    42     else if(ql <= mid){
    43         update(ql, mid, v, l, mid, nodenum << 1);
    44         update(mid + 1, qr, v, mid + 1, r, nodenum << 1 | 1);
    45     }
    46     else
    47         update(ql, qr, v, mid + 1, r, nodenum << 1 | 1);
    48 }
    49 int query(int x, int l, int r, int nodenum){
    50     if(l == r)
    51         return tree[nodenum].v;
    52     pushdown(nodenum);
    53     int mid = (l + r) >> 1;
    54     if(x > mid)
    55         return query(x, mid + 1, r, nodenum << 1 | 1);
    56     else
    57         return query(x, l, mid, nodenum << 1); 
    58 }
    59 
    60 
    61 int main(){
    62     while(scanf("%d", &n) && n){
    63         memset(a, 0, sizeof(a));
    64         buildTree(0, n - 1, 1);
    65         for(int i = 0; i < n; i++){
    66             int tma, tmb;
    67             scanf("%d %d", &tma, &tmb);
    68             tma--, tmb--;
    69             update(tma, tmb, 1, 0, n - 1, 1);
    70         }
    71         for(int i = 0; i < n; i++){
    72             if(i) 
    73                 putchar(' ');
    74             printf("%d", query(i, 0, n - 1, 1));
    75         }
    76         puts("");
    77     }
    78 }

    题目:

    Color the ball

    Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 20089    Accepted Submission(s): 10016


    Problem Description
    N个气球排成一排,从左到右依次编号为1,2,3....N.每次给定2个整数a b(a <= b),lele便为骑上他的“小飞鸽"牌电动车从气球a开始到气球b依次给每个气球涂一次颜色。但是N次以后lele已经忘记了第I个气球已经涂过几次颜色了,你能帮他算出每个气球被涂过几次颜色吗?
     
    Input
    每个测试实例第一行为一个整数N,(N <= 100000).接下来的N行,每行包括2个整数a b(1 <= a <= b <= N)。
    当N = 0,输入结束。
     
    Output
    每个测试实例输出一行,包括N个整数,第I个数代表第I个气球总共被涂色的次数。
     
    Sample Input
    3 1 1 2 2 3 3 3 1 1 1 2 1 3 0
     
    Sample Output
    1 1 1 3 2 1
     
    Author
    8600
  • 相关阅读:
    FFmpeg入门,简单播放器
    Linux系统编译Win32版本adb
    检测目标程序ELF bit是32还是64
    Swift编程资料全集
    Swift编程资料总结
    cocos2d-html5学习之三-为sprite添加触摸事件
    Cocos2d-html5学习笔记二
    cocos2d-x学习笔记一
    NSViewAnimation进行视图和窗口动画
    Cocoa中NSAnimation动画简介
  • 原文地址:https://www.cnblogs.com/bolderic/p/6945036.html
Copyright © 2020-2023  润新知