【模板】线段树区间修改
区间修改:
区间修改过程类似于区间询问,例如将[ul, ur]内的所有元素都加上v,则进行如下操作:
当当前区间被区间[ul, ur]所包含时,
当前的节点值加上区间长度(r - l + 1)乘以v
对当前节点的lazy-tag加上v,修改结束
否则,将当前节点的lazy-tag下传,分别修改左孩子和右孩子(一定条件下),然后更新此节点的值
lazy-tag下传:
如果当前节点没有lazy-tag,直接return
否则:1. 将左孩子右孩子分别加上lazy-tag * 区间长度的值
2. 左孩子和右孩子的懒惰标记加上lazy-tag
3. 当前节点的lazy-tag清零
注意区间询问的时候也要lazy-tag下传
【代码:】
1 //线段树区间修改 2 #include<iostream> 3 #include<cstdio> 4 using namespace std; 5 6 const int MAXN = 100000 + 1; 7 8 int n, m, a[MAXN]; 9 struct Segment { 10 long long sum, lazy; 11 Segment() { 12 sum = lazy = 0; 13 } 14 }t[MAXN << 2]; 15 16 void Build(int o, int l, int r) { 17 if(l == r) t[o].sum = a[l]; 18 else { 19 int mid = (l + r) >> 1; 20 Build(o << 1, l, mid); 21 Build(o << 1|1, mid + 1, r); 22 t[o].sum = t[o << 1].sum + t[o << 1|1].sum; 23 } 24 } 25 void down(int o, int len) { 26 if(!t[o].lazy) return; 27 t[o << 1].sum += t[o].lazy * (len - (len >> 1)); 28 t[o << 1|1].sum += t[o].lazy * (len >> 1); 29 t[o << 1].lazy += t[o].lazy; 30 t[o << 1|1].lazy += t[o].lazy; 31 t[o].lazy = 0; 32 } 33 void Update(int o, int l, int r, int ul, int ur, int v) { 34 if(ul <= l && r <= ur) { 35 t[o].sum += (r - l + 1) * v; 36 t[o].lazy += v; 37 } 38 else { 39 down(o, r - l + 1); 40 int mid = (l + r) >> 1; 41 if(ul <= mid) Update(o << 1, l, mid, ul, ur, v); 42 if(ur > mid) Update(o << 1|1, mid + 1, r, ul, ur, v); 43 t[o].sum = t[o << 1].sum + t[o << 1|1].sum; 44 } 45 } 46 long long Query(int o, int l, int r, int ql, int qr) { 47 if(ql <= l && r <= qr) { 48 return t[o].sum; 49 } 50 int mid = (l + r) >> 1; 51 long long ret = 0; 52 down(o, r - l + 1); 53 if(ql <= mid) ret += Query(o << 1, l, mid, ql, qr); 54 if(qr > mid) ret += Query(o << 1|1, mid + 1, r, ql, qr); 55 return ret; 56 } 57 int main() { 58 scanf("%d%d", &n, &m); 59 for(int i = 1; i <= n; ++i) 60 scanf("%d", &a[i]); 61 Build(1, 1, n); 62 while(m--) { 63 int fl, x, y; 64 scanf("%d%d%d", &fl, &x, &y); 65 if(fl == 1) { 66 int k; 67 scanf("%d", &k); 68 Update(1, 1, n, x, y, k); 69 } 70 else printf("%lld\n", Query(1, 1, n, x, y)); 71 } 72 }
模板测试题目传送门
转载于:https://www.cnblogs.com/devilk-sjj/p/9044841.html
【模板】线段树区间修改相关推荐
- python:线段树区间修改 + 区间查询 模板 + 坑点总结
from functools import reduceclass SegTree:'''支持增量更新,覆盖更新,序列更新,任意RMQ操作基于二叉树实现初始化:O(1)增量更新或覆盖更新的单次操作复杂 ...
- hdu3966 树链剖分点权模板+线段树区间更新/树状数组区间更新单点查询
点权树的模板题,另外发现树状数组也是可以区间更新的.. 注意在对链进行操作时方向不要搞错 线段树版本 #include<bits/stdc++.h> using namespace std ...
- POJ 2777 Count Color (线段树区间修改 + 状态压缩)
题目链接:POJ 2777 Count Color [题目大意] 给你 n 块板子, 编号1--n , 板子的颜色最多30种, 初始时 板子的颜色都是 1: 有两种操作 1 .把给定区间的板子染成一 ...
- HDU 1698 Just a Hook (线段树区间修改+区间查询)
题目链接: 传送门 题意:Pudge对装备钩子进行若干次的强化,强化分为三种分别对应的价值是1,2,3,在经历过若干次操作后,输出钩子对应的总价值,每次强化都是对钩子进行区间修改 解题思路:在明白了题 ...
- hdu1698(线段树/区间修改/求和)
hdu1698"Just a Hook" 题意: 有一个区间s [1,n],每一节si的初始价值为1.定义操作:x y val,将区间[x,y]中的每一个小节的价值改为val.问: ...
- 1631 小鲨鱼在51nod小学(线段树区间修改+单点查询:不用下传lazy的区间修改)
题目描述: 1631 小鲨鱼在51nod小学 鲨鱼巨巨2.0(以下简称小鲨鱼)以优异的成绩考入了51nod小学.并依靠算法方面的特长,在班里担任了许多职务. 每一个职务都有一个起始时间A和结束时间B, ...
- codeforces:E2. Array and Segments (Hard version)【线段树 + 区间修改】
分析 思路很简单 遍历每个作为最大值,然后区间不包含当前最大值的都可以减掉 easy version就可以这样暴力解决 然后求出最大差值 暴力解法 import sys input = sys.std ...
- UVa 11992 (线段树 区间修改) Fast Matrix Operations
比较综合的一道题目. 二维的线段树,支持区间的add和set操作,然后询问子矩阵的sum,min,max 写完这道题也是醉醉哒,代码仓库里还有一份代码就是在query的过程中也pushdown向下传递 ...
- 【UOJ 53】线段树区间修改
[题目描述]: 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.求出某区间每一个数的和 [输入描述]: 第一行包含两个整数N.M,分别表示该数列数字的个数和操作的总个数. ...
最新文章
- tensorflow inceptionv3参数笔记
- 01-迭代开发的基本需求和Scrum标准
- python的__get__、__set__、__delete__(1)
- 通俗说一下python和人工智能有什么关系
- IPFS网络是如何运行的(p2p网络)
- 3. 无重复字符的最长子串 golang
- 25个优秀的设计机构网站设计案例
- JVM内存模型与GC回收器
- 神经网络中的Softmax激活函数
- MATLAB中的线性插值
- 机器学习算法-10贝叶斯信念网络、聚类算法、基于密度的方法DBSCAN
- wi ndows防火墙,WinXP自带防火墙设置详细讲解
- Qt之切换语言的方法(传统数组法与Qt语言家)
- Google推出即时通讯软件Hello
- Latex中的花体格式
- windows 下配置 Nginx 常见问题
- 炉石传说 android,炉石传说安卓版
- 软件开发人员如何记笔记
- html怎么写海贼王旗帜图片,海贼王精美旗帜套图
- 【2022 CCPC 华为云计算挑战赛】1005 带权子集和 (NTT 优化dp)