结构和思想
作用
常用来维护区间信息,可在 O(log2 (n)) 的时间复杂度内实现单点修改,区间修改,区间查询(区间求
和,区间最大值,区间最小值)等操作
线段树的基本结构(以区间加为例)
使用堆式存储结构,将每个长度不为 的区间划分为左右俩个区间递归求解,并通过合并左右俩个子区
间得到该区间信息
单点修改+区间查询
1
n个数:a1,a2,a3,…,an
q个操作:
1. 1 x d 修改ax=d
2. 2 l r 查询[l,r]最小值,并求出最小值出现了多少次
1 |
|
复杂的信息合并
2
n个数:a1,a2,a3,…,an
q个操作:
1. 1 x d 修改ax=d
2. 2 l r 查询[l,r]最大子段和,即从[l,r]中找到[l’,r’],其数值之和最大
1 |
|
区间打标记以及下传
区间修改与区间查询
3
n个数:a1,a2,a3,…,an
q个操作:
1. 1 l r d 修改a[l~r]+=d
2. 2 l r 查询[l,r]最大a[i]
懒标记
懒标记就是一种延迟对节点的修改,每次修改时,仅修改极大的区间节点,并在这下节点增加懒标记,
若在遍历过程中遇到懒标记则将懒标记下传至子节点并修改子节点,若当前为叶子节点则不下传,回溯
过程合并左右儿子信息
标记永久化(不建议)
标记下传:
- 压标记,清空标记
- 打标记 (合并标记,更新信息)
1 |
|
1 | //封装版 |
4
1 |
|
复杂的标记问题,标记的顺序
5
n个数:a1,a2,a3,…,an
q个操作:
1. 1 l r d 令a[lr]+dr]*d
2. 2 l r d 令a[l
3. 3 l r d 令a[lr]=dr]之和mod(1e9+7)
4. 4 l r 查询 a[l
分析:
a * 1 + d //区间加
a * d + 0 //区间乘
a * 0 + d //区间赋值
1 |
|
6
1 |
|
线段树上二分
7
n个数:a1,a2,a3,…,an
q个操作:
1. 1 x d 修改ax=d
2. 2 l r d 查询最小i(l<=i<=r),使ai>=d; 若不存在则输出-1
1 |
|
权值线段树
9
1 |
|
9
权值线段树之字典树
异或第k小 (涉及 异或、字典树)
给n个数字:a1,a2,…,an
m个询问,每次给定两个数字x k,询问 a1 xor x, a2 xor x,…,an xor x 中从小到大排序中第k小的元素
1 |
扫描线与权值线段树
10
mex
有一个长度为n的数组a1,a2,…,an
回答q个询问,每次给一个区间[l,r],询问这个区间内最小没有出现的自然数
11[HDU3974]
1 | //要写哭了 T-T |
1 | //from repeater |