考虑一个问题,在一个二维的坐标面上,要对一个矩形内所有的点进行区间加(减),或求某一个范围内的区间和,这时候,一维线段树已经不适用了,那应该怎么办?来个二维的线段树(线段树套线段树)
考虑某一个x的坐标值,在它上面建一颗线段树,维护这个X值上y轴的区间信息,这个问题可以看成一个子问题,在一个数轴内进行区间修改区间查询,(很明显的普通线段树)。
在对每一个坐标都进行这样的操作后,想一想线段树的核心思想,不就是将这些单一的结点逐步合成一个区间吗,那x轴上的这一系列的点不也可以慢慢合成一个个区间?
//左边的数轴即为单个x值的维护y轴,右边的即为区间这一系列x轴上的点维护的y轴
没错,想到这里基本就完成了,可是在代码实现上, 二维貌似还有点困难…
那就抽象一点,记得一维线段树时用来存储的是一个数组 int tree[maxn << 2], 那我们定义一个结构体,把它当成y轴上的线段树,然后再将x轴上的那一层线段树当成普通线段树,seg tree[maxn << 2],(seg是定义的结构体的名称)。
在进行区间操作时,你需要了解一下标记永久化(csdn自己查
接下来,你就可以利用封装好的y层线段树加上一个普通的一维线段树开始乱搞了…详情看代码
// 忘记是哪个oj网站上的哪一题了…洛谷4514可以自己拿去练练手
#include <bits/stdc++.h>
#define endl '\n'
using namespace std;
using ll = long long;
using pii = pair<int, int>;
using db = double;
const int maxn = 3003;
int n, m;
#define lson l, mid, num << 1
#define rson mid + 1, r, num << 1 | 1
struct xds
{
int tree[maxn], tag[maxn];
// 内层线段树,也就是y轴上的
void update(int y, int y1, int val, int l, int r, int num)
{
tree[num] = max(tree[num], val);
if (l == y && r == y1)
{
tag[num] =