题意解读:对于序列a[n],支持三种操作:1.对区间每个数乘上一个数 2.对区间每个数加上一个数 3.求区间和 解题思路:由于支持乘、加两种区间修改操作,是线段树的另一种典型应用:多个懒标记 显然,这里需要两个懒标记,mul表示对子节点区间每个数乘mul,add表示对子节点区间每个数加上add,节点定义如下: structNode{...
如果当前节点区间完全被[l,r]包含,则修改当前节点区间的信息sum += (r-l+1) * k,并给当前节点懒标记赋值add += k,懒标记的值表示当前节点的所有子节点都要加上add;因此,线段树能维护的懒标记必须是可累加的(如加法,异或)。 如果当前节点区间与[l,r]不相交,则不做任何操作; 如果当前节点区间与[l,r]...
洛谷OJ:P3372 【模板】线段树 1(分块 or 线段树?) 思路:这道题出发点就是为了练习线段树的板子题,但是我另外用了分块算法做了这道题,后面也会贴出相应的线段树解法。 分块算法: #include<set> #include<queue> #include<vector> #include<string> #include<math.h> #include<stdio.h> #include<string.h...
主席树 对于原序列的每一个前缀 \([1 \ldots i]\) 建立出一棵线段树维护值域上每个数出现的次数,则这棵树是可减的。 维护一棵权值线段树,每个节点 \(rt\) 保存数值为 \([ lson[rt], rson[rt] ]\) 的数的个数。 对于每次询问的 \([L,R]\) 范围内第 \(k\) 小的数, 设\(t_1\) 为第 ...
模板如下: //主席树#include<iostream>#include<algorithm>#include<vector>usingnamespacestd;constintmaxn=100001;intnum[maxn],num2[maxn];introot[maxn];structnode{intl,r,val;}Node[maxn*40];inttot=0,node_cnt=0;//前一个版本,当前版本,当前值域,要插入的值voidmodify(intpre,int&now,intl,intr...
【模板】线段树 2 - 洛谷www.luogu.com.cn/problem/P3373 思路: 区间更新既有加法又有乘法就要考虑他们的先后顺序问题。数组tree[rt]表示rt节点的值,也就是这个区间的和;mark1[rt]表示rt节点的乘法lazy标记;mark2[rt]表示rt节点的加法lazy标记。当进行区间乘以v的更新时,tree[rt]要乘v,mark1[rt]要乘...
洛谷P3834【模板】可持久化线段树2(主席树)洛⾕P3834【模板】可持久化线段树2(主席树)题⽬背景 这是个⾮常经典的主席树⼊门题——静态区间第 k k⼩。数据已经过加强,请使⽤主席树。同时请注意常数优化。题⽬描述 如题,给定 n n个整数构成的序列 a a,将对于指定的闭区间 [l,r][l,r]...
可持久化线段树入门(单点更新模板) 一、可持久化线段树的用处 显然从名字上可以看出来这是一种建立在线段树上的小升级。 从一个小问题可以引入: 当我们使用线段树处理一堆询问时,我们在一棵树上进行更新(如单点更新的操作),如果某一时刻突然让你把手头上的操作停下来,并且询问在你没有进行上一步操作时,树的...
有一个长为 nn 的序列 aa,以及一个大小为 kk 的窗口。现在这个从左边开始向右滑动,每次滑动一个单位,求出每次滑动后窗口中的最大值和最小值。 例如: The array is [1,3,-1,-3,5,3,6,7][1,3,−1,−3,5,3,6,7], and k = 3k=3。
这两个操作都属于线段树的基本操作 前置——宏定义# #defineN100011#definelsonrt<<1#definersonrt<<1|1#defineintlonglong 由于我特别懒,不想写什么rt<<1rt<<1之类的东西,所以直接宏定义就好了,还有,为了不改intint,我直接把intint宏定义为longlonglonglong,省的麻烦(我真的是懒到家了) ...