zoukankan      html  css  js  c++  java
  • kuangbin专题七:E题 Just a Hook ( 延迟标记,区间更新(赋值)求和 )

    HDU  1698  ( 延迟标记,区间更新(赋值)求和 )
    Just a Hook
    题目链接
    http://acm.hdu.edu.cn/showproblem.php?pid=1698

    ////////////////////////////////////
    注意  :  lazy思想的简单应用,所谓的lazy思想就是成段更新,用一个变量标记该段被更新过,
    便把这个消息传给子树。lazy思想用通俗的话讲就是查找到该处,就更新,否则不要动。

    题意 : 有一根长度  1 -- n  的钩子    刚开始钩子为 铜质 每单位长度价值为一
            输入  x , y , z ; 代表 x -- y 数段 的 钩子 的价值 被更改为  z
    最后输出长为 n 的钩子的总价值  

    #include<cstdio>
    #include<algorithm>
    
    using namespace std ; 
    
    
    typedef struct ndoe{
        int l , r ; 
        int sum , flag ; 
    }Lnode;
    
    Lnode tree[2000000] ;
    
    void build(int i , int l , int r){
        //  建立线段树 
        tree[i].l = l ;        // 初始化 树节点的   数段范围 
        tree[i].r = r ; 
        tree[i].flag = 0 ;     //  初始化 树节点的  标记 
        tree[i].sum = (l-r+1) ; // 初始化当前树节点 所代表的 和 
        if(l==r){     // 当左边等于右边     意味着当前节点是树的最后一个节点 
            return;    //    因为上边已经给节点赋值   所以此处不需要再赋值  
        }
        int mid = (l+r)/2 ; 
        build(2*i , l , mid) ;        //  建立左右 孩子 数段 
        build(2*i+1 , mid+1 , r) ; 
    }
    
    void update(int l , int r , int flag , int i){
        // 修改 区间 值                                                      } 
        if(r<tree[i].l||tree[i].r < l)                                //       } 递归 返回的条件 
            return;                                                   //       }   
        if(l<=tree[i].l && tree[i].r <=r){                            //       }
            tree[i].flag = flag ; //  延迟标记                        //       }    
            tree[i].sum = (tree[i].r - tree[i].l + 1) * tree[i].flag ; //      }
            return;                                                   //       }
        }                                                             //       }
        
        if(tree[i].flag){// 用到被标记的 数段 时  延迟标记向下传递         //  } 当 递归 进行到《《以前》》被标记 过得 
            int ll=2*i , rr = 2*i+1 ;//                                    //  }   数段时  首先 把 此数段 的标记 
            tree[ll].flag = tree[i].flag ;                                 //  } 向下 传递   然后计算  此 数段  
            tree[ll].sum = (tree[ll].r - tree[ll].l + 1) * tree[ll].flag ; //  } 左右两个字数段的值 
            tree[rr].flag = tree[i].flag  ;                                //  } 
            tree[rr].sum = ( tree[rr].r - tree[rr].l + 1) * tree[rr].flag ; // }
            tree[i].flag = 0;  
        }
        
        update(l , r , flag , 2*i) ;                                       // }  从父亲数段 向左右节点数段递归 查找要求中 
        update(l , r , flag , 2*i+1) ;                                    //  }  需要被标记的数段   并 用上面的代码 标记之 
                                                                          //  }  同时 结束递归返回 
        tree[i].sum = tree[2*i].sum + tree[2*i+1].sum ;        // 主数段将两个通过递归计算出结果的值相加求和 
    }
    
    
    int main(){
        int t , n  , m , x , y , z , Case = 0  ;
        scanf("%d" , &t) ; 
        while(t--){
            scanf("%d%d" , &n , &m ) ; 
            build(1 ,1 , n ) ; // 建立节电标号为 1 -> n 根节点为 1 的线段树 
            for(int i=1 ; i<=m  ; i++){
                scanf("%d%d%d" , &x , &y , &z) ; 
                update(x , y , z , 1 ) ; 
            }
            printf("Case %d: The total value of the hook is %d.
    " ,++Case , tree[1].sum  ) ; 
            
        }
        return 0 ; 
    }
    /*   题解链接(没看懂可以看看这个题解) 
    http://blog.sina.com.cn/s/blog_87cb8e680100vek9.html*/ 
    #include <cstdio>
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    
    using namespace std ;
    
    #define maxn 110000
    int num[maxn] ;
    int n , q ;
    int a , b , c ;
    
    struct node {
        int l ,
            r ,
            sum ,
            flag ;
    };
    
    node tree[maxn*4] ;
    
    void build(int root , int l , int r) {
    
        tree[root].l = l ;
        tree[root].r = r ;
        tree[root].flag = 0 ;
        if(l == r ) {
            tree[root].sum = 1 ;
            return;
        }
    
        int mid = (l+r)/2 ;
        build(root*2 , l , mid ) ;
        build(root*2+1 , mid+1 , r ) ;
    
        tree[root].sum = tree[root*2].sum = tree[root*2+1].sum ;
    }
    
    void update(int root , int l , int r , int value ) {
        if(r < tree[root].l || tree[root].r < l) {
            return;
        }
    
        if(l <= tree[root].l && tree[root].r <= r) {
            tree[root].sum = (tree[root].r - tree[root].l + 1 ) * value ;
            tree[root].flag = value ;
            return;
        }
    
        if(tree[root].flag) {
            tree[root*2].flag = tree[root].flag ;
            tree[root*2].sum = (tree[root*2].r - tree[root*2].l + 1 ) * tree[root*2].flag ;
    
            tree[root*2+1].flag = tree[root].flag ;
            tree[root*2+1].sum = (tree[root*2+1].r - tree[root*2+1].l + 1 ) * tree[root*2+1].flag ;
    
            tree[root].flag = 0 ;
        }
    
        update(root*2 , l , r , value ) ;
        update(root*2+1 , l  ,r , value ) ;
        tree[root].sum = tree[root*2].sum + tree[root*2+1].sum ;
    }
    
    int main() {
        int t ;
        scanf("%d" , &t) ;
        for(int Case=1 ; Case<=t ; Case++) {
    
            scanf("%d" , &n) ;
    
            scanf("%d" , &q) ;
            build(1 , 1 , n ) ;
            for(int i=1;  i<=q ; i++) {
                scanf("%d %d %d" , &a , &b , &c) ;
                update(1 , a , b , c ) ;
            }
    
            printf("Case %d: The total value of the hook is %d.
    " , Case, tree[1].sum) ;
        }
        return 0 ;
    }
    View Code
  • 相关阅读:
    简单的股票分析系统
    gtest日志在工程项目中的应用
    doctest初次体验
    python写的读取json配置文件
    logbook日志系统
    python3 pyodbc简单使用
    numpy中dtype
    python获取代码行号
    Python操作SQLServer示例(转)
    log4j与log4j.properties的配置
  • 原文地址:https://www.cnblogs.com/yi-ye-zhi-qiu/p/7698795.html
Copyright © 2011-2022 走看看