线段树基础模板(加减乘除AND最值查询)

区间求和最值 

class SegmentTree {  
public:  
    SegmentTree(const vector<int>& data, int mod = 1e12) : n(data.size()) {  
        this -> data = data;  
        this -> mod = mod;
        tree.resize(4 * n);  
        lazy_add.assign(4 * n, 0);  
        lazy_mul.assign(4 * n, 1);  
        build(0, 0, n - 1);  
    }  
    //区间修改 范围(此处[1, n]) 修正值 加减 true|乘除false 
    void update_range(int l, int r, int value, bool op) {  
        update_range(0, 0, n - 1, l - 1, r - 1, value, op);  
    }  
    
    //区间查询求和
    int query_range(int l, int r) {  
        return query_range(0, 0, n - 1, l - 1, r - 1) % mod;  
    }  
    //单点修改 目标点 目标值
    void update_point(int idx, int value) {  
        update_point(0, 0, n - 1, idx - 1, value);  
    }  
    //返回[l,r]区间最小值
    int range_min(int l, int r) {  
        return range_min(0, 0, n - 1, l - 1, r - 1);  
    }  
	//返回[l,r]区间最大值
    int range_max(int l, int r) {  
        return range_max(0, 0, n - 1, l - 1, r - 1);  
    }  

private:  
    vector<int> data, tree;  
    vector<int> lazy_add, lazy_mul;  
    int n, mod;  

    void build(int node, int start, int end) {  
        if (start == end) {  
            tree[node] = data[start];  
        } 
        else 
        {  
            int mid = (start + end) / 2;  
            build((node << 1) + 1, start, mid);  
            build((node << 1) + 2, mid + 1, end);  
            tree[node] = tree[(node << 1) + 1] + tree[(node << 1) + 2];  
        }  
    }  

    void apply_lazy(int node, int start, int end) {  
        if (lazy_mul[node] != 1) 
        {  
            tree[node] = tree[node] * lazy_mul[node] % mod;  
            if (start != end) {  
                lazy_mul[(node << 1) + 1] = lazy_mul[(node << 1) + 1] * lazy_mul[node] % mod;  
                lazy_mul[(node << 1) + 2] = lazy_mul[(node << 1) + 2] * lazy_mul[node] % mod;  
                lazy_add[(node << 1) + 1] = lazy_add[(node << 1) + 1] * lazy_mul[node] % mod;  
                lazy_add[(node << 1) + 2] = lazy_add[(node << 1) + 2] * lazy_mul[node] % mod;  
            }  
            lazy_mul[node] = 1;  
        }  

        if (lazy_add[node] != 0) 
        {  
            tree[node] =  tree[node] + (end - start + 1) * lazy_add[node] % mod;  
            if (start != end) {  
                lazy_add[(node << 1) + 1] = lazy_add[(node << 1) + 1] + lazy_add[node] % mod;  
                lazy_add[(node << 1) + 2] = lazy_add[(node << 1) + 2] + lazy_add[node] % mod;  
            }  
            lazy_add[node] = 0;  
        }  
    }  

    void update_range(int node, int start, int end, int l, int r, int value, bool op) 
    {  
        apply_lazy(node, start, end);  

        if(start > end || start > r || end < l) return;  
        
        if (start >= l && end <= r) 
        {  
            if (op == true) 
            {  
                lazy_add[node] = lazy_add[node] + value % mod;  // Add  
            } 
            else if (op == false) 
            {  
                lazy_mul[node] = lazy_mul[node] * value % mod;   // Multiply  
                lazy_add[node] = lazy_add[node] * value % mod;   // Adjust for additive effect of multiplier  
            }  
            apply_lazy(node, start, end);  
            return;  
        }  

        int mid = (start + end) / 2;  
        update_range((node << 1) + 1, start, mid, l, r, value, op);  
        update_range((node << 1) + 2, mid + 1, end, l, r, value, op);  
        tree[node] = tree[(node << 1) + 1] + tree[(node << 1) + 2];  
    }  

    int query_range(int node, int start, int end, int l, int r) {  
        apply_lazy(node, start, end);  

        if (start > end || start > r || end < l) {  
            return 0;  
        }  
        if (start >= l && end <= r) {  
            return tree[node] % mod;  
        }  

        int mid = (start + end) >> 1;  
        return query_range((node << 1) + 1, start, mid, l, r) % mod + query_range((node << 1) + 2, mid + 1, end, l, r) % mod;  
    }  

    void update_point(int node, int start, int end, int idx, int value) {  
        if (start == end) {  
            tree[node] = value;  
        } else {  
            int mid = (start + end) / 2;  
            if (start <= idx && idx <= mid) {  
                update_point((node << 1) + 1, start, mid, idx, value);  
            } else {  
                update_point((node << 1) + 2, mid + 1, end, idx, value);  
            }  
            tree[node] = tree[(node << 1) + 1] + tree[(node << 1) + 2];  
        }  
    }  

    int range_min(int node, int start, int end, int l, int r) {  
        apply_lazy(node, start, end);  
        
        if (start > end || start > r || end < l) {  
            return numeric_limits<int>::max();  
        }  
        if (start >= l && end <= r) {  
            return tree[node];  
        }  

        int mid = (start + end) / 2;  
        return min(range_min((node << 1) + 1, start, mid, l, r),  
                   range_min((node << 1) + 2, mid + 1, end, l, r));  
    }  

    int range_max(int node, int start, int end, int l, int r) {  
        apply_lazy(node, start, end);  

        if (start > end || start > r || end < l) {  
            return numeric_limits<int>::min();  
        }  
        if (start >= l && end <= r) {  
            return tree[node];  
        }  

        int mid = (start + end) / 2;  
        return max(range_max((node << 1) + 1, start, mid, l, r), range_max((node << 1) + 2, mid + 1, end, l, r));  
    }  
};  

区间修改求和

class SegmentTree {  
public:  
    SegmentTree(const vector<int>& data, int mod = 1e12) : n(data.size()) {  
        this -> data = data;  
        this -> mod = mod;
        tree.resize(4 * n);  
        lazy_add.assign(4 * n, 0);  
        lazy_mul.assign(4 * n, 1);  
        build(0, 0, n - 1);  
    }  
    //区间修改 范围(此处[1, n]) 修正值 加减 true|乘除false 
    void update_range(int l, int r, int value, bool op) {  
        update_range(0, 0, n - 1, l - 1, r - 1, value, op);  
    }  
    
    //区间查询求和
    int query_range(int l, int r) {  
        return query_range(0, 0, n - 1, l - 1, r - 1) % mod;  
    }  
    //单点修改 目标点 目标值
    void update_point(int idx, int value) {  
        update_point(0, 0, n - 1, idx - 1, value);  
    }  

private:  
    vector<int> data, tree;  
    vector<int> lazy_add, lazy_mul;  
    int n, mod;  

    void build(int node, int start, int end) {  
        if (start == end) {  
            tree[node] = data[start];  
        } 
        else 
        {  
            int mid = (start + end) / 2;  
            build((node << 1) + 1, start, mid);  
            build((node << 1) + 2, mid + 1, end);  
            tree[node] = tree[(node << 1) + 1] + tree[(node << 1) + 2];  
        }  
    }  

    void apply_lazy(int node, int start, int end) {  
        if (lazy_mul[node] != 1) 
        {  
            tree[node] = tree[node] * lazy_mul[node] % mod;  
            if (start != end) {  
                lazy_mul[(node << 1) + 1] = lazy_mul[(node << 1) + 1] * lazy_mul[node] % mod;  
                lazy_mul[(node << 1) + 2] = lazy_mul[(node << 1) + 2] * lazy_mul[node] % mod;  
                lazy_add[(node << 1) + 1] = lazy_add[(node << 1) + 1] * lazy_mul[node] % mod;  
                lazy_add[(node << 1) + 2] = lazy_add[(node << 1) + 2] * lazy_mul[node] % mod;  
            }  
            lazy_mul[node] = 1;  
        }  

        if (lazy_add[node] != 0) 
        {  
            tree[node] =  tree[node] + (end - start + 1) * lazy_add[node] % mod;  
            if (start != end) {  
                lazy_add[(node << 1) + 1] = lazy_add[(node << 1) + 1] + lazy_add[node] % mod;  
                lazy_add[(node << 1) + 2] = lazy_add[(node << 1) + 2] + lazy_add[node] % mod;  
            }  
            lazy_add[node] = 0;  
        }  
    }  

    void update_range(int node, int start, int end, int l, int r, int value, bool op) 
    {  
        apply_lazy(node, start, end);  

        if(start > end || start > r || end < l) return;  
        
        if (start >= l && end <= r) 
        {  
            if (op == true) 
            {  
                lazy_add[node] = lazy_add[node] + value % mod;  // Add  
            } 
            else if (op == false) 
            {  
                lazy_mul[node] = lazy_mul[node] * value % mod;   // Multiply  
                lazy_add[node] = lazy_add[node] * value % mod;   // Adjust for additive effect of multiplier  
            }  
            apply_lazy(node, start, end);  
            return;  
        }  

        int mid = (start + end) / 2;  
        update_range((node << 1) + 1, start, mid, l, r, value, op);  
        update_range((node << 1) + 2, mid + 1, end, l, r, value, op);  
        tree[node] = tree[(node << 1) + 1] + tree[(node << 1) + 2];  
    }  

    int query_range(int node, int start, int end, int l, int r) {  
        apply_lazy(node, start, end);  

        if (start > end || start > r || end < l) {  
            return 0;  
        }  
        if (start >= l && end <= r) {  
            return tree[node] % mod;  
        }  

        int mid = (start + end) >> 1;  
        return query_range((node << 1) + 1, start, mid, l, r) % mod + query_range((node << 1) + 2, mid + 1, end, l, r) % mod;  
    }  

    void update_point(int node, int start, int end, int idx, int value) {  
        if (start == end) {  
            tree[node] = value;  
        } else {  
            int mid = (start + end) / 2;  
            if (start <= idx && idx <= mid) {  
                update_point((node << 1) + 1, start, mid, idx, value);  
            } else {  
                update_point((node << 1) + 2, mid + 1, end, idx, value);  
            }  
            tree[node] = tree[(node << 1) + 1] + tree[(node << 1) + 2];  
        }  
    }  
};  

单点修改求最小值 

class SegmentTree {  
private:  
    vector<int> tree;       // 存储线段树  
    vector<int> data;       // 原始数据  
    int n;  

    // 构建线段树  
    void build(int node, int start, int end) {  
        if (start == end) {  
            tree[node] = data[start]; // 叶子节点  
        } else {  
            int mid = (start + end) / 2;  
            build(2 * node + 1, start, mid);        // 左子树  
            build(2 * node + 2, mid + 1, end);      // 右子树  
            tree[node] = min(tree[2 * node + 1], tree[2 * node + 2]); // 合并结果  
        }  
    }  

    // 修改某个点的值  
    void update(int node, int start, int end, int idx, int val) {  
        if (start == end) {  
            data[idx] = val; // 更新原始数据  
            tree[node] = val; // 更新线段树  
        } else {  
            int mid = (start + end) / 2;  
            if (idx <= mid) {  
                update(2 * node + 1, start, mid, idx, val); // 更新左子树  
            } else {  
                update(2 * node + 2, mid + 1, end, idx, val); // 更新右子树  
            }  
            tree[node] = min(tree[2 * node + 1], tree[2 * node + 2]); // 合并结果  
        }  
    }  

    int range_min(int node, int start, int end, int l, int r) 
    {  
        if (start > end || start > r || end < l) {  
            return numeric_limits<int>::max();  
        }  
        if (start >= l && end <= r) {  
            return tree[node];  
        }  

        int mid = (start + end) / 2;  
        return min(range_min((node << 1) + 1, start, mid, l, r),  
                   range_min((node << 1) + 2, mid + 1, end, l, r));  
    }  
public:  
    SegmentTree(const vector<int>& arr) {  
        data = arr;  
        n = arr.size();  
        tree.resize(4 * n); // 线段树的大小  
        build(0, 0, n - 1); // 构建线段树  
    }  

    void update(int idx, int val) {  
        update(0, 0, n - 1, idx - 1, val); // 更新值  
    }  

    int range_min(int L, int R) {  
        return range_min(0, 0, n - 1, L - 1, R - 1); // 查询范围的最小值  
    }  
};  

单点最大值

class SegmentTree {  
private:  
    vector<int> tree;       // 存储线段树  
    vector<int> data;       // 原始数据  
    int n;  

    // 构建线段树  
    void build(int node, int start, int end) {  
        if (start == end) {  
            tree[node] = data[start]; // 叶子节点  
        } else {  
            int mid = (start + end) / 2;  
            build(2 * node + 1, start, mid);        // 左子树  
            build(2 * node + 2, mid + 1, end);      // 右子树  
            tree[node] = max(tree[2 * node + 1], tree[2 * node + 2]); // 合并结果  
        }  
    }  

    // 修改某个点的值  
    void update(int node, int start, int end, int idx, int val) {  
        if (start == end) {  
            data[idx] = val; // 更新原始数据  
            tree[node] = val; // 更新线段树  
        } else {  
            int mid = (start + end) / 2;  
            if (idx <= mid) {  
                update(2 * node + 1, start, mid, idx, val); // 更新左子树  
            } else {  
                update(2 * node + 2, mid + 1, end, idx, val); // 更新右子树  
            }  
            tree[node] = max(tree[2 * node + 1], tree[2 * node + 2]); // 合并结果  
        }  
    }  

    // 查询区间的最大值  
     int range_max(int node, int start, int end, int l, int r) {  
        //apply_lazy(node, start, end);  

        if (start > end || start > r || end < l) {  
            return numeric_limits<int>::min();  
        }  
        if (start >= l && end <= r) {  
            return tree[node];  
        }  

        int mid = (start + end) / 2;  
        return max(range_max((node << 1) + 1, start, mid, l, r), range_max((node << 1) + 2, mid + 1, end, l, r));  
    }  

public:  
    SegmentTree(const vector<int>& arr) {  
        data = arr;  
        n = arr.size();  
        tree.resize(4 * n); // 线段树的大小  
        build(0, 0, n - 1); // 构建线段树  
    }  

    void update(int idx, int val) {  
        update(0, 0, n - 1, idx, val); // 更新值  
    }  

    int range_max(int L, int R) {  
        return range_max(0, 0, n - 1, L, R); // 查询范围的最大值  
    }  
};  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值