[hiho 22]线段树-lazy标记的下放
题目描述
之前提到过,线段树之所以更新查询快,是因为区间更新有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标记的下放相关推荐
- POJ 3468 线段树+lazy标记
lazy标记 Time Limit:5000MS Memory Limit:131072KB 64bit IO Format:%I64d & %I64u Submit S ...
- HYSBZ - 1798 Seq 维护序列seq 线段树lazy标记
传送门 这道题属实是线段树的道比刷题,又加又乘的,当然还可能会有乘除,阶乘等等可能的情况. 对于这道题,主要的一个就是怎么记录lazy标记,首先的话一个数组是肯定不行的,设乘的为lazy,加的为add ...
- 20.CF817F MEX Queries 线段树(Lazy标记练习)
20.CF817F MEX Queries 离散化+区间覆盖+区间反转线段树 个人Limitの线段树题单题解主目录:Limitの线段树题单 题解目录_HeartFireY的博客-CSDN博客 要求维护 ...
- POJ 3225 线段树+lazy标记
lazy写崩了--. 查了好久 /* U-> [l,r]–>1 I-> [1,l-1] [r+1,+无穷] –>0 D-> [l,r]–>0 C-> [1,l ...
- CodeForces - 817F MEX Queries(线段树lazy序)
题目链接:点击查看 题目大意:初始时有一个空的集合,需要执行 n 次操作: 1 l r:将区间 [ l , r ] 内未出现的数加入到集合中 2 l r:将区间 [ l , r ] 内出现的数字全部删 ...
- 对空防御的训练 改编自BZOJ3165 (线段树永久化标记 李超线段树)
对空防御的训练 256MB / 1s ; defense.cpp / c / pas / in / out [题目描述] 秋月十分擅长对空作战.尽管如此,必要的训练也不能懈怠. 在一次训练中,会有m个 ...
- [hiho 21]线段树-离散化
题目描述 区间覆盖问题,区间绝对位置并不重要,重要的是各个更新的区间段之间的相对位置关系. 举例而言,离散化将区间更新[1,100], [2, 50]更换为区间更新[1,4], [2,3]. 离散化可 ...
- Tree(树链剖分+线段树延迟标记)
Tree http://poj.org/problem?id=3237 Time Limit: 5000MS Memory Limit: 131072K Total Submissions: 12 ...
- 线段树 +懒标记 + P3372 【模板】线段树 1
题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.求出某区间每一个数的和 输入格式 第一行包含两个整数N.M,分别表示该数列数字的个数和操作的总个数. 第二行包含 ...
最新文章
- 删除链表中全部值为k的节点
- 全面掌握ISO8583报文协议
- sql注入学习——时间盲注
- appium 环境搭建(不推荐安装此版本appium,推荐安装appium desktop)
- Android笔记 显式意图demo
- Python项目实践:天天向上的力量
- vs2010 mysql linq to sql 系列_linq to sql简单使用
- CFS 调度器数据结构篇
- php 冗余代码检测,冗余代码检查工具Simian | 求索阁
- 【openGL基础系列】之画一个正方体玩玩吧
- 0/1背包问题 - 如何理解 解空间
- ANDROID_MARS学习笔记_S01原始版_009_下载文件
- Python编程练习:判断字符串是否为回文
- mysql创建新用户
- 有1、2、3、4四个数字,可以组成多少个互不相同且无重复的三位数?都是多少?
- vxe-table vxe-pager 如何使用分页,自定义分页
- SpringBoot定时任务说明
- ROS TF 常用接口函数
- SpringBoot整合Elastricsearch + LogStash + Kibana太简单了!
- 英语基础太差,能学好编程吗?