区间求和 II -LintCode

在类的构造函数中给一个整数数组, 实现两个方法 query(start, end) 和 modify(index, value):

对于 query(start, end), 返回数组中下标 start 到 end 的 和。
对于 modify(index, value), 修改数组中下标为 index 上的数为 value.

注意事项:
在做此题前,建议先完成以下三题:
线段树的构造
线段树的查询
线段树的修改

样例:
给定数组 A = [1,2,7,8,5].

query(0, 2), 返回 10.
modify(0, 4), 将 A[0] 修改为 4.
query(0, 1), 返回 6.
modify(2, 1), 将 A[2] 修改为 1.
query(2, 4), 返回 14.

挑战 :
O(logN) time for query and modify.

#ifndef C207_H
#define C207_H
#include<iostream>
#include<vector>
using namespace std;
class SegmentNode{
public:
    int start, end;
    long long sum;
    SegmentNode *left, *right;
    SegmentNode(int start, int end, long long sum=0)
    {
        this->start = start, this->end = end, this->sum = sum;
        this->left = this->right = NULL;
    }
    static SegmentNode *build(vector<int> &A, int start, int end){
        if (start > end)
            return NULL;
        SegmentNode* root = new SegmentNode(start, end, A[start]);
        if (start == end) 
            return root;
        int mid = (start + end) / 2;
        root->left = build(A,start, mid);
        root->right = build(A,mid + 1, end);

        root->sum = 0;
        if (root->left)
            root->sum += root->left->sum;
        if (root->right)
            root->sum += root->right->sum;
        return root;
    }
    static void modifyRecur(SegmentNode* root, int index, int value){
        if (root->start == root->end)
        {
            if (root->start == index)
                root->sum = value;
            return;
        }
        int mid = (root->start + root->end) / 2;
        if (index > mid)
            modifyRecur(root->right, index, value);
        else
            modifyRecur(root->left, index, value);
        root->sum = 0;
        if (root->left)
            root->sum += root->left->sum;
        if (root->right)
            root->sum += root->right->sum;
    }
    static long long queryRecur(SegmentNode* root, int start, int end){
        if (start > root->end || end<root->start)
            return 0;
        if (start <= root->start && end >= root->end)
            return root->sum;
        int l = queryRecur(root->left, start, end);
        int r = queryRecur(root->right, start, end);
        return l + r;
    }
};
class Solution {
public:
    /* you may need to use some attributes here */

    /*
    * @param A: An integer array
    */
    Solution(vector<int> A) {
        // do intialization if necessary
        node = SegmentNode::build(A, 0, A.size() - 1);
    }
    /*
    * @param start: An integer
    * @param end: An integer
    * @return: The sum from start to end
    */
    long long query(int start, int end) {
        // write your code here
        return SegmentNode::queryRecur(node, start, end);
    }
    /*
    * @param index: An integer
    * @param value: An integer
    * @return: nothing
    */
    void modify(int index, int value) {
        // write your code here
        SegmentNode::modifyRecur(node, index, value);   
    }   
    SegmentNode* node;
};
#endif
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值