题目描述

之前提到过,线段树之所以更新查询快,是因为区间更新有lazy标记使得不需要每次都操作到叶子节点。

但是如果要操作一个节点时,其父节点上的lazy标记应当被释放,否则该节点无法得到最新的正确结果。

因而lazy标记下放的策略是在需要操作某个节点的子节点时,将该节点的lazy标记全部下放。见第69行。

同时应当注意,给某个节点增加lazy标记时,不要忘了修改该节点的相关统计值。因为更新完该节点后还要马上修改其父节点的统计值。见第80行。

代码如下:

#include <stdio.h>#define N 100005
#define MODE_ADD 0
#define MODE_SET 1typedef
struct _seg_tree_ {int left, right;int add;int setv;int val;_seg_tree_ *lson = NULL, *rson = NULL;_seg_tree_(int left_idx, int right_idx, int value): left(left_idx), right(right_idx), add(0), setv(-1), val(value) {}
} seg_tree, *pseg_tree;pseg_tree construct_seg_tree(int left, int right) {if (left == right) {int val;scanf("%d", &val);return new seg_tree(left, right, val);}int mid = left + (right - left) / 2;pseg_tree lson = construct_seg_tree(left, mid);pseg_tree rson = construct_seg_tree(mid + 1, right);pseg_tree ans = new seg_tree(left, right, lson->val + rson->val);ans->lson = lson;ans->rson = rson;return ans;
}void lazy_down(pseg_tree proot) {if (proot->setv != -1) {if (proot->lson != NULL) {proot->lson->setv = proot->setv;proot->lson->add = 0;proot->lson->val = proot->setv * (proot->lson->right - proot->lson->left + 1);proot->rson->setv = proot->setv;proot->rson->add = 0;proot->rson->val = proot->setv * (proot->rson->right - proot->rson->left + 1);}proot->setv = -1;}if (proot->add != 0) {if (proot->lson != NULL) {proot->lson->add += proot->add;proot->rson->add += proot->add;proot->lson->val += proot->add * (proot->lson->right - proot->lson->left + 1);proot->rson->val += proot->add * (proot->rson->right - proot->rson->left + 1);}proot->add = 0;}
}void modify_seg_tree(pseg_tree proot, int left, int right, int val, int type) {if (left == proot->left && right == proot->right) {if (type == MODE_ADD) {proot->add += val;proot->val += val * (right - left + 1);} else {proot->setv = val;proot->val = val * (right - left + 1);proot->add = 0;}return;}int mid = proot->left + (proot->right - proot->left) / 2;lazy_down(proot);if (left > mid) {modify_seg_tree(proot->rson, left, right, val, type);}else if (right <= mid) {modify_seg_tree(proot->lson, left, right, val, type);}else {modify_seg_tree(proot->rson, mid + 1, right, val, type);modify_seg_tree(proot->lson, left, mid, val, type);}proot->val = proot->lson->val + proot->rson->val;
}int main(){int n, m;scanf("%d%d", &n, &m);pseg_tree proot = construct_seg_tree(0, n);int type, left, right, val;for (int i = 0; i < m; i++) {scanf("%d%d%d%d", &type, &left, &right, &val);modify_seg_tree(proot, left, right, val, type);printf("%d\n", proot->val);}return 0;
}

转载于:https://www.cnblogs.com/xblade/p/4542781.html

[hiho 22]线段树-lazy标记的下放相关推荐

  1. POJ 3468 线段树+lazy标记

    lazy标记   Time Limit:5000MS     Memory Limit:131072KB     64bit IO Format:%I64d & %I64u  Submit S ...

  2. HYSBZ - 1798 Seq 维护序列seq 线段树lazy标记

    传送门 这道题属实是线段树的道比刷题,又加又乘的,当然还可能会有乘除,阶乘等等可能的情况. 对于这道题,主要的一个就是怎么记录lazy标记,首先的话一个数组是肯定不行的,设乘的为lazy,加的为add ...

  3. 20.CF817F MEX Queries 线段树(Lazy标记练习)

    20.CF817F MEX Queries 离散化+区间覆盖+区间反转线段树 个人Limitの线段树题单题解主目录:Limitの线段树题单 题解目录_HeartFireY的博客-CSDN博客 要求维护 ...

  4. POJ 3225 线段树+lazy标记

    lazy写崩了--. 查了好久 /* U-> [l,r]–>1 I-> [1,l-1] [r+1,+无穷] –>0 D-> [l,r]–>0 C-> [1,l ...

  5. CodeForces - 817F MEX Queries(线段树lazy序)

    题目链接:点击查看 题目大意:初始时有一个空的集合,需要执行 n 次操作: 1 l r:将区间 [ l , r ] 内未出现的数加入到集合中 2 l r:将区间 [ l , r ] 内出现的数字全部删 ...

  6. 对空防御的训练 改编自BZOJ3165 (线段树永久化标记 李超线段树)

    对空防御的训练 256MB / 1s ; defense.cpp / c / pas / in / out [题目描述] 秋月十分擅长对空作战.尽管如此,必要的训练也不能懈怠. 在一次训练中,会有m个 ...

  7. [hiho 21]线段树-离散化

    题目描述 区间覆盖问题,区间绝对位置并不重要,重要的是各个更新的区间段之间的相对位置关系. 举例而言,离散化将区间更新[1,100], [2, 50]更换为区间更新[1,4], [2,3]. 离散化可 ...

  8. Tree(树链剖分+线段树延迟标记)

    Tree http://poj.org/problem?id=3237 Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 12 ...

  9. 线段树 +懒标记 + P3372 【模板】线段树 1

    题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.求出某区间每一个数的和 输入格式 第一行包含两个整数N.M,分别表示该数列数字的个数和操作的总个数. 第二行包含 ...

最新文章

  1. 删除链表中全部值为k的节点
  2. 全面掌握ISO8583报文协议
  3. sql注入学习——时间盲注
  4. appium 环境搭建(不推荐安装此版本appium,推荐安装appium desktop)
  5. Android笔记 显式意图demo
  6. Python项目实践:天天向上的力量
  7. vs2010 mysql linq to sql 系列_linq to sql简单使用
  8. CFS 调度器数据结构篇
  9. php 冗余代码检测,冗余代码检查工具Simian | 求索阁
  10. 【openGL基础系列】之画一个正方体玩玩吧
  11. 0/1背包问题 - 如何理解 解空间
  12. ANDROID_MARS学习笔记_S01原始版_009_下载文件
  13. Python编程练习:判断字符串是否为回文
  14. mysql创建新用户
  15. 有1、2、3、4四个数字,可以组成多少个互不相同且无重复的三位数?都是多少?
  16. vxe-table vxe-pager 如何使用分页,自定义分页
  17. SpringBoot定时任务说明
  18. ROS TF 常用接口函数
  19. SpringBoot整合Elastricsearch + LogStash + Kibana太简单了!
  20. 英语基础太差,能学好编程吗?

热门文章

  1. 记忆化搜索,动态规划(旅行,uva 1347)
  2. ascii码占多少个字节
  3. ASP.NET网站与Discuz!NT论坛整合
  4. 第118章 SQL函数 REVERSE
  5. BUUCTF-reverse-reverse3(超级详细)
  6. 蓝桥到此一游—2012年C/C++ B组蓝桥杯省赛真题(一)
  7. LaTeX 表格的处理
  8. 【春秋云境.com】每月10号1024会员日,双倍体验惊喜不停
  9. 解决了:android 有些手机出现了《安全风险/发现病毒》等报毒(除插件)
  10. Python——hashlib模块(MD5校验)