目录
分析
线段树每种操作的实现区别的细粒度高,不好封装,并且一般在算法题中出现。
线段树代码量很大
线段树具有堆结构,一般采用静态数组实现最优,当然动态树也可以,改天更新
线段树处理动态修改查询区间非常强大,很少有别的数据结构能与之媲美
线段树进阶操作还有持久化,操作回溯,优化建图,树上二分等,这些扩展持续学习中,改日更新
DSA模板(静态数组、侵入式)
Version I : 单点赋值 + 区间加法查询
Version II: 单点加法 + 区间加法查询
Version III: 区间赋值 + 区间加法查询
Version IV: 区间加法 + 区间最小值查询
Version V: 区间加法 + 区间最小值计数 + 区间最小值查询
一下代码,自行参考学习
/*
* static (instrusive and non-generic) segment tree implemented based on linear integral array
* generally, the DSA arc supports those operations onto an integer array:
* 1: single point modify(assignment) [ array[index] = value ]
* 2: range modify
2.1: assignment[ array[first : last : 1 step] = value ]
2.2: addition[ array[first : last : 1 step] += value ]
3: range query
3.1 query by addition [ SumOf{ array[first : last : 1 step] } ]
3.2 query be minimum [ MinOf{ array[first : last : 1 step] } ]
3.2.0 query by minimum while recording the count [ CountOf{ MinOf{ array[first : last : 1 step] } } ]
*/
/*
* version I
* only support [single point modify] and [segment query by the [addition] at certain ranges]
*/
#if defined(SINGLE_POINT_MODIFY) && defined(SEGMENT_QUERY) && defined(UPDATE_ADDITION)
#include <array>
constexpr auto __MAX__ { static_cast<int>(1e3) };
std::array<int, __MAX__ + 1> sequence {};
std::array<int, __MAX__ << 2 | 1> addition {};
constexpr int left(int index) noexcept { return x << 1; }
constexpr int right(int index) noexcept { return x << 1 | 1; }
constexpr void update(int index) noexcept {
addition[index] = addition[left(index)] + addition[right(index)];
}
void build(int first, int last, int index) noexcept {
if(first + 1 == last)
return (void) { addition[first] = sequence[first] };
int middle { (first + last) / 2 };
build(first, middle, left(index));
build(middle, last, right(index));
update(index);
}
int query(int first, int last, int current_first, int current_last, int index) noexcept {
if(first <= current_first && last >= current_last) return addition[index];
int middle { (current_first + current_last)/2 };
return (
first < middle ? query(first, last, current_first, middle, left(index)) : 0
+ last >= middle ? query(first, last, middle, current_last, right(index)) : 0 );
}
void change(int position, int value, int first, int last, int index) noexcept {
if(first + 1 == last) return (void) (addition[index] = v);
int middle { (first + last)/2 };
if(position < middle) change(position, value, first, middle, left(index));
else change(position, value, middle, last, right(index));
update(index);
}
#endif
/*
* version II
* only support [range modify] and [segment query by the [addition] at certain ranges]
*/
#if defined(RANGE_MODIFY) && defined(SEGMENT_QUERY) && defined(UPDATE_ADDITION)
#include <array>
constexpr auto __MAX__ { static_cast<int>(1e3) };
std::array<int, __MAX__ + 1> sequence {};
std::array<int, __MAX__ << 2 | 1> addition {};
std::array<int, __MAX__ << 2 | 1> lazy {};
constexpr int left(int index) noexcept { return x << 1; }
constexpr int right(int index) noexcept { return x << 1 | 1; }
constexpr void update(int index) noexcept {
addition[index] = addition[left(index)] + addition[right(index)];
}
void build(int first, int last, int index) noexcept {
if(first + 1 == last)
return (void) { addition[first] = sequence[first] };
int middle { (first + last) / 2 };
build(first, middle, left(index));
build(middle, last, right(index));
update(index);
}
void down(int first, int last, int index) noexcept {
int middle { (first + last) / 2 };
if(lazy[index] > 0) {
lazy[left(index)] = lazy[right(index)] = lazy[index];
addition[left(index)] = (middle - first) * lazy[index];
addition[right(index)] = (last - middle) * lazy[index];
lazy[i

最低0.47元/天 解锁文章
734

被折叠的 条评论
为什么被折叠?



