题目:
https://leetcode.com/problems/range-sum-query-mutable/
思路:
使用数据结构线段树,在NumArray的构造函数中递归构造线段树。
//线段树节点
class Node
{
public:
int Min, Max, sum;//Min, Max表示该节点的区间为[Min,Max]
Node* left, *right;
Node(int a, int b, int c) :Min(a), Max(b), sum(c), left(NULL), right(NULL){}
};
class NumArray {
public:
Node* root;
vector<int> arr;
NumArray(vector<int> &nums)
{
if (!nums.empty())
{
root = buildtree(nums, 0, nums.size() - 1).first;
arr = vector<int>(nums);
}
else
root = NULL;
}
pair<Node*, int> buildtree(vector<int> &nums, int l, int r)
{
if (l == r)
{
Node* res = new Node(l, r, nums[l]);
return make_pair(res, nums[l]);
}
else
{
int mid = ((l + r) & 1) == 0 ? (l + r) >> 1 : ((l + r) >> 1) + 1;
pair<Node*, int> ret1 = buildtree(nums, l, mid - 1), ret2 = buildtree(nums, mid, r);
Node* res = new Node(l, r, ret1.second + ret2.second);
res->left = ret1.first;
res->right = ret2.first;
return make_pair(res, ret1.second + ret2.second);
}
}
void update(int i, int val)
{
update_core(root, i, val);
arr[i] = val;//重要!一定要改变arr对应的元素
}
void update_core(Node* root, int i, int val)
{
if (root == NULL)
return;
if (i >= root->Min && i <= root->Max)
{
root->sum -= arr[i];
root->sum += val;
update_core(root->left, i, val);
update_core(root->right, i, val);
}
}
int sumRange(int i, int j) {
return seach(root, i, j);
}
int seach(Node* root, int i, int j)
{
if (root == NULL || i>j)
return -1;
if (root->Min == i && j == root->Max)
return root->sum;
int mid = ((root->Min + root->Max) & 1) == 0 ? (root->Min + root->Max) >> 1 : ((root->Min + root->Max) >> 1) + 1;
if (mid <= i)
return seach(root->right, i, j);
else if (j <= mid - 1)
return seach(root->left, i, j);
else
{
return seach(root->left, i, mid - 1) + seach(root->right, mid, j);
}
}
};
// Your NumArray object will be instantiated and called as such:
// NumArray numArray(nums);
// numArray.sumRange(0, 1);
// numArray.update(1, 10);
// numArray.sumRange(1, 2);