#203 Segment Tree Modify

本文介绍了一种在最大值段树中修改指定节点值的方法,并确保更新后树的每个节点仍保持正确的最大值属性。通过递归算法实现节点值的更新。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述:

For a Maximum Segment Tree, which each node has an extra value max to store the maximum value in this node's interval.

Implement a modify function with three parameter rootindex and value to change the node's value with [start, end] = [index, index] to the new given value. Make sure after this change, every node in segment tree still has the max attribute with the correct value.

 Notice

We suggest you finish problem Segment Tree Build and Segment Tree Query first.

Example

For segment tree:

                      [1, 4, max=3]
                    /                \
        [1, 2, max=2]                [3, 4, max=3]
       /              \             /             \
[1, 1, max=2], [2, 2, max=1], [3, 3, max=0], [4, 4, max=3]

if call modify(root, 2, 4), we can get:

                      [1, 4, max=4]
                    /                \
        [1, 2, max=4]                [3, 4, max=3]
       /              \             /             \
[1, 1, max=2], [2, 2, max=4], [3, 3, max=0], [4, 4, max=3]

or call modify(root, 4, 0), we can get:

                      [1, 4, max=2]
                    /                \
        [1, 2, max=2]                [3, 4, max=0]
       /              \             /             \
[1, 1, max=2], [2, 2, max=1], [3, 3, max=0], [4, 4, max=0]
Challenge 

Do it in O(h) time, h is the height of the segment tree.

题目思路:

题目要求更改max value,只有子树的max value都改好了,才能知道当前root的max value是个啥。用recursion就可以了。

Mycode(AC = 104ms):

/**
 * Definition of SegmentTreeNode:
 * class SegmentTreeNode {
 * public:
 *     int start, end, max;
 *     SegmentTreeNode *left, *right;
 *     SegmentTreeNode(int start, int end, int max) {
 *         this->start = start;
 *         this->end = end;
 *         this->max = max;
 *         this->left = this->right = NULL;
 *     }
 * }
 */
class Solution {
public:
    /**
     *@param root, index, value: The root of segment tree and 
     *@ change the node's value with [index, index] to the new given value
     *@return: void
     */
    void modify(SegmentTreeNode *root, int index, int value) {
        // write your code here
        if (index < root->start || index > root->end) {
            return;
        }
        else if (root->start == index && root->end == index) {
            root->max = value;
        }
        else if (root->start == root->end) {
            return;
        }
        else {
            int modified_max = INT_MIN;
            if (root->left) {
                modify(root->left, index, value);
                modified_max = max(modified_max, root->left->max);
            }
            if (root->right) {
                modify(root->right, index, value);
                modified_max = max(modified_max, root->right->max);
            }
            
            root->max = modified_max;
            
        }
        
    }
};

帮我看一下这段代码为什么在洛谷P3919 RE了: #include <bits/stdc++.h> using namespace std; // Persistent Segment Tree template<class Value> class PersistentSGT { public: PersistentSGT(int _n) : n(_n) { root.push_back(0); build(root[0], 1, n, nullptr); } PersistentSGT(Value* begin, Value* end) { n = end - begin; root.push_back(0); build(root[0], 1, n, begin); } void modify(int ver, int idx, Value val) { root.push_back(root[ver]); modify(root.back(), 1, n, idx, val); } Value query(int ver, int idx) { root.push_back(root[ver]); return query(root.back(), 1, n, idx); } private: void build(int& cur, int l, int r, Value* arr) { tr.emplace_back(); cur = tr.size() - 1; if (l == r) tr[cur].val = arr ? arr[l - 1] : Value(); else { int mid = (l + r) / 2; build(tr[cur].ls, l, mid, arr); build(tr[cur].rs, mid + 1, r, arr); } } void modify(int& cur, int l, int r, int idx, Value val) { tr.push_back(tr[cur]); cur = tr.size() - 1; if (l == r) { tr[cur].val = val; return ; } int mid = (l + r) / 2; if (idx <= mid) modify(tr[cur].ls, l, mid, idx, val); else modify(tr[cur].rs, mid + 1, r, idx, val); } int query(int cur, int l, int r, int idx) { if (l == r) return tr[cur].val; int mid = (l + r) / 2; if (idx <= mid) return query(tr[cur].ls, l, mid, idx); else return query(tr[cur].rs, mid + 1, r, idx); } int n; struct Node { int ls, rs; Value val; }; vector<Node> tr; vector<int> root; }; const int MAX_N = 1e6 + 50; int n, m, a[MAX_N]; int main() { ios::sync_with_stdio(false); cin.tie(0), cout.tie(0); cin >> n >> m; for (int i = 1; i <= n; i++) cin >> a[i]; PersistentSGT<int> t(a + 1, a + n + 1); for (int i = 1, ver, opt, idx, val; i <= m; i++) { cin >> ver >> opt >> idx; if (opt == 1) { cin >> val; t.modify(ver, idx, val); } else cout << t.query(ver, idx) << &#39;\n&#39;; } return 0; }
03-22
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值