📌  相关文章
📜  细分树|设置2(范围最小查询)(1)

📅  最后修改于: 2023-12-03 15:27:33.513000             🧑  作者: Mango

细分树 | 设置2 (范围最小查询)

概述

细分树(或称为李超树)是一种支持动态数组修改、区间查询的数据结构。而设置2是细分树中的一个操作,它的作用是查询一个区间中最小的元素。本文将介绍如何实现细分树设置2操作,并给出相应的代码示例。

实现思路

细分树是一种基于思想的数据结构,其主要目的是对动态数组进行修改和查询。在细分树中,我们将每个数组元素看作是一颗树,那么整个数组就可以看作是一棵森林。然后我们就可以对这个森林进行一些操作,从而实现对动态数组的修改和查询。

细分树的实现过程可以分为两个步骤:

  1. 预处理:将原始数组按一定规律划分为若干个子数组,并在每个子数组上构建出相应的线段树。

  2. 查询过程:根据查询时给定的区间,将该区间中的所有子数组分别进入相应的线段树进行查询。

细分树设置2操作的实现基于以上思路,具体步骤如下:

  1. 针对每个子数组,用线段树保存该子数组中每个位置的最小值。

  2. 对于给定的查询区间,将该区间中的所有子数组分别进入相应的线段树中查询最小值。

  3. 取所有线段树中查询出的最小值作为结果。

代码实现

下面是细分树设置2操作的代码实现,采用C++语言编写:

// 线段树节点
struct SegNode {
    int l, r; // 区间左右端点
    int val; // 该区间内的最小值
} tree[N * M * 4];

// 细分树主体函数
void dfs(int l, int r, int dep, int idx) {
    // 区间长度小于等于阈值,直接用单次线性扫描更新
    if (r - l + 1 <= BOUND) {
        for (int i = l; i <= r; ++i) {
            if (a[idx][i] < a[idx][tree[dep].val]) {
                tree[dep].val = i;
            }
        }
        return;
    }

    // 将当前区间分为两半,分别递归处理
    int mid = (l + r) / 2;
    dfs(l, mid, dep * 2, idx);
    dfs(mid + 1, r, dep * 2 + 1, idx);

    // 更新当前节点的信息
    tree[dep].val = a[idx][tree[dep * 2].val] < a[idx][tree[dep * 2 + 1].val] ? tree[dep * 2].val : tree[dep * 2 + 1].val;
}

// 设置2函数
inline int query(int lx, int rx, int ly, int ry) {
    int res = INF;

    // 遍历每个子数组,分别进入相应的线段树进行查询
    for (int i = lx; i <= rx; ++i) {
        res = min(res, a[i][tree[1].val]);
        int l = ly, r = ry, dep = 1;
        while (l < r) {
            int mid = (l + r) / 2;
            if (mid >= ly) {
                dep *= 2;
                if (tree[dep].val >= l && tree[dep].val <= mid) {
                    dep += 1;
                }
                r = mid;
            } else {
                l = mid + 1;
                dep = dep * 2 + 1;
                if (tree[dep].val >= l && tree[dep].val <= ry) {
                    dep -= 1;
                }
            }
        }
        res = min(res, a[i][tree[dep].val]);
    }
    return res;
}

上面的代码中,函数dfs用于预处理,在每个区间上构建线段树并更新最小值。函数query则是设置2操作的具体实现,它首先遍历所有子数组,再将每个子数组对应的线段树中的最小值取出。最后选出所有最小值中的最小值,作为整个查询区间的最小值。