Algorithm 区间的最小范围查询和更新

Algorithm 区间的最小范围查询和更新,algorithm,data-structures,rmq,Algorithm,Data Structures,Rmq,我需要一个支持三种操作的范围最小查询数据结构: -用数组A初始化[n] -更新(i,j,v)-将v添加到范围A[i]…A[j] -查询(i,j)-从范围A[i]…A[j]中查找最小元素 更新和查询都必须在O(log n)时间内运行,并且结构必须占用O(n)空间。谢谢您的帮助我通过惰性传播技术成功地做到了这一点 使用向量而不是数组进行初始化。 它很容易变成一个最大的查询结构。。。将所有最小值替换为最大值,将数字210000000替换为-210000000 #include <algorith

我需要一个支持三种操作的范围最小查询数据结构:
-用数组A初始化[n]
-更新(i,j,v)-将v添加到范围A[i]…A[j]
-查询(i,j)-从范围A[i]…A[j]中查找最小元素


更新和查询都必须在
O(log n)
时间内运行,并且结构必须占用
O(n)
空间。

谢谢您的帮助
我通过
惰性传播
技术成功地做到了这一点

使用向量而不是数组进行初始化。
它很容易变成一个最大的查询结构。。。将所有最小值替换为最大值,将数字210000000替换为-210000000

#include <algorithm>
#include <vector>
#include <cmath>
using namespace std;

class IntervalTree
{
    int* tree;
    int* lazy;
    int n;

    void build_tree(const vector<int>& v, int node, int a, int b)
    {
        if (a > b) return;

        if (a == b) { tree[node] = v[a]; return; }

        build_tree(v, node * 2, a, (a + b) / 2);
        build_tree(v, node * 2 + 1, 1 + (a + b) / 2, b);
        tree[node] = min(tree[node * 2], tree[node * 2 + 1]);
    }

    void update_lazy(int node, int a, int b)
    {
        tree[node] += lazy[node];

        if (a != b) 
        { 
            lazy[node * 2] += lazy[node];
            lazy[node * 2 + 1] += lazy[node];
        }

        lazy[node] = 0;
    }

    void update_tree(int node, int a, int b, int i, int j, int value)
    {
        if (lazy[node] != 0) update_lazy(node,a,b);

        if (a > b || a > j || b < i) return;

        if (a >= i && b <= j) 
        {
            tree[node] += value;
            if (a != b) 
            {
                lazy[node * 2] += value;
                lazy[node * 2 + 1] += value;
            }
            return;
        }

        update_tree(node * 2, a, (a + b) / 2, i, j, value);
        update_tree(1 + node * 2, 1 + (a + b) / 2, b, i, j, value);

        tree[node] = min(tree[node * 2], tree[node * 2 + 1]);
    }

    int query_tree(int node, int a, int b, int i, int j)
    {
        if (a > b || a > j || b < i) return 2100000000;

        if (lazy[node] != 0) update_lazy(node,a,b);

        if (a >= i && b <= j) return tree[node];

        int q1 = query_tree(node * 2, a, (a + b) / 2, i, j);
        int q2 = query_tree(1 + node * 2, 1 + (a + b) / 2, b, i, j);

        return min(q1, q2);
    }

public:
    IntervalTree(const vector<int>& v)
    {
        n = v.size();

        int s = 2*pow(2, ceil(log2(v.size())));

        tree = new int[s];

        lazy = new int[s];

        memset(lazy, 0, sizeof lazy);

        build_tree(v, 1, 0, n - 1);
    }

    void update(int idx1, int idx2, int add)
    {
        update_tree(1, 0, n - 1, idx1, idx2, add);
    }

    int query(int idx1, int idx2)
    {
        return query_tree(1, 0, n - 1, idx1, idx2);
    }
};
#包括
#包括
#包括
使用名称空间std;
类间隔树
{
int*树;
int*懒惰;
int n;
无效构建树(常量向量&v、整数节点、整数a、整数b)
{
如果(a>b)返回;
如果(a==b){tree[node]=v[a];return;}
构建_树(v,节点*2,a,(a+b)/2);
构建_树(v,节点*2+1,1+(a+b)/2,b);
树[节点]=min(树[节点*2],树[节点*2+1]);
}
void update_lazy(int节点、int a、int b)
{
树[节点]+=惰性[节点];
如果(a!=b)
{ 
惰性[节点*2]+=惰性[节点];
惰性[节点*2+1]+=惰性[节点];
}
惰性[节点]=0;
}
无效更新树(int节点,int a,int b,int i,int j,int值)
{
如果(lazy[node]!=0)更新_lazy(node,a,b);
如果(a>b | a>j | b=i&b b|a>j|b=i&b