zoukankan      html  css  js  c++  java
  • hihocoder 1080 线段树(区间更新)

      题目链接:http://hihocoder.com/problemset/problem/1080 , 两种操作的线段树(区间更新)。

      这道题前一段时间一直卡着我,当时也是基础不扎实做不出来,今天又想了想其实还是比较简单的,也只能怪自己太弱了。


      这道题坑就坑在是有两个操作:set和add,所以lazy标记数组就需要两个,但是有一点要考虑的是一个区间上set与add的先后关系——如果对于一个区间set和add标记同时存在,那么应该如果处理:一种情况set在add之前,那么就按照正常顺序来就可以了;另一种情况add在set之前,那么这个add操作就取消,直接set操作就可以了。

      所以更新线段树的一个区间的时候,如果是set操作,那么就把add的标记清理掉;如果是add操作,那么就正常进行。这样的话就保证两个标记同时出现的时候是先set再add的,这样的话就不会出错。

    #include <iostream>
    #include <cstdio>
    #include <vector>
    #include <cmath>
    #include <string>
    #include <string.h>
    #include <algorithm>
    using namespace std;
    #define LL __int64
    #define eps 1e-8
    #define INF INT_MAX
    #define lson l , m , rt << 1
    #define rson m + 1 , r , rt << 1 | 1
    const int MOD = 10000007; 
    const int maxn = 100000 + 5;
    const int N = 100000 + 5;
    int sum[maxn << 2] , col_add[maxn << 2] , col_set[maxn << 2];
    void PushUp(int rt)
    {
        sum[rt] = sum[rt << 1] + sum[rt << 1 | 1];
    }
    void build(int l , int r , int rt)
    {
        if(l == r) {
            scanf("%d" , &sum[rt]);
            return;
        }
        int m = (l + r) >> 1;
        build(lson);
        build(rson);
        PushUp(rt);
    }
    void PushDown(int rt , int len)
    {            //在PushDown()函数里就是先执行set操作再执行add操作
        if(col_set[rt]) {
            col_set[rt << 1] = col_set[rt << 1 | 1] = col_set[rt];
            col_add[rt << 1] = col_add[rt << 1 | 1] = 0;    //同样清除掉add的标记,当时少了这句Debug了好久
            sum[rt << 1] = (len - (len >> 1)) * col_set[rt];
            sum[rt << 1 | 1] = (len >> 1) * col_set[rt];
            col_set[rt] = 0;
        }
        if(col_add[rt] != 0) {
            col_add[rt << 1] += col_add[rt];
            col_add[rt << 1 | 1] += col_add[rt];
            sum[rt << 1] += (len - (len >> 1)) * col_add[rt];
            sum[rt << 1 | 1] += (len >> 1) * col_add[rt];
            col_add[rt] = 0;
        } 
    }
    void update(int L , int R , int x , int ch , int l , int r , int rt)
    {
        if(L <= l && R >= r) {
            if(ch) {
                sum[rt] = (r - l + 1) * x;
                col_set[rt] = x;
                col_add[rt] = 0;    //清除掉add的标记
            } else {
                sum[rt] += (r - l + 1) * x;
                col_add[rt] += x;
            }
            return;
        }
        PushDown(rt , r - l + 1);
        int m = (l + r) >> 1;
        if(L > m)
            update(L , R , x , ch , rson);
        else if(R <= m)
            update(L , R , x , ch , lson);
        else {
            update(L , R , x , ch , lson);
            update(L , R , x , ch , rson);
        }
        PushUp(rt);
    }
    int main()
    {
        int n , m , a , b , c , ch;
        scanf("%d %d" , &n , &m);
        build(1 , n + 1 , 1);
        while(m--) {
            scanf("%d %d %d %d" , &ch , &a , &b , &c);
            update(a + 1 , b + 1 , c , ch , 1 , n + 1 , 1);
            printf("%d
    " , sum[1]);
        }
        return 0;
    }
  • 相关阅读:
    基于ABP落地领域驱动设计-04.领域服务和应用服务的最佳实践和原则
    基于ABP落地领域驱动设计-03.仓储和规约最佳实践和原则
    基于ABP落地领域驱动设计-02.聚合和聚合根的最佳实践和原则
    基于ABP落地领域驱动设计-01.全景图
    Es6-find&map&filter&reduce
    vue之监听事件
    list map互相转换
    springcloud 返回实体类忽略属性
    Apache NetBeans IDE 12.3 双击无反应怪事
    前端--- 前端调试经验总结
  • 原文地址:https://www.cnblogs.com/H-Vking/p/4297272.html
Copyright © 2011-2022 走看看