zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    无限维
    黎曼流形
    why we need virtual key word
    TOJ 4119 Split Equally
    TOJ 4003 Next Permutation
    TOJ 4002 Palindrome Generator
    TOJ 2749 Absent Substrings
    TOJ 2641 Gene
    TOJ 2861 Octal Fractions
    TOJ 4394 Rebuild Road
  • 原文地址:https://www.cnblogs.com/bolderic/p/6945036.html
Copyright © 2011-2022 走看看