C++ 区域和的查询 线段树法

给定一个整数数组nums,求这个整数数组中,下标i到下标j之间的数字和(i<=j),a[i]+a[i+1]+…+a[j]。在求和的过程中,可能需要更新数组的某个元素a[i]。

#include <vector>
//线段树的构造
void build_segment_tree(std::vector<int>& nums, std::vector<int>& value, int pos, int left, int right)
{
 if (left == right)
 {
  value[pos] = nums[left];
  return;
 }
 int mid = (left + right) / 2;
 build_segment_tree(nums, value, 2 * pos + 1, left, mid);
 build_segment_tree(nums, value, 2 * pos + 2, mid + 1, right);
 value[pos] = value[2 * pos + 1] + value[2 * pos + 2];
}
//线段树的求和
int sum_range_segment_tree(std::vector<int>& value, int pos, int left, int right, int qleft, int qright)
{
 if (qleft > right || qright < left)
 {
  return 0;
 }
 if (qleft <= left && qright >= right)
 {
  return value[pos];
 }
 int mid = (left + right) / 2;
 return sum_range_segment_tree(value, 2 * pos + 1, left, mid, qleft, qright) + sum_range_segment_tree(value, 2 * pos + 2, mid + 1, right, qleft, qright);
}
//线段树的更新
void update_segment_tree(std::vector<int>& value, int pos, int left, int right, int index, int new_value)
{
 if (left == right && left == index)
 {
  value[pos] = new_value;
  return;
 }
 int mid = (left + right) / 2;
 if (index <= mid)
 {
  update_segment_tree(value, 2 * pos + 1, left, mid, index, new_value);
 }
 else
 {
  update_segment_tree(value, 2 * pos + 2, mid + 1, right, index, new_value);
 }
 value[pos] = value[2 * pos + 1] + value[2 * pos + 2];
}
class NumArray
{
public:
 NumArray(std::vector<int> nums)
 {
  if (nums.size()==0)
  {
   return;
  }
  int n = nums.size() * 4;
  for (int i = 0; i < n; i++)
  {
   _value.push_back(0);
  }
  build_segment_tree(nums, _value , 0, 0, nums.size() - 1);
  _right_end = nums.size() - 1;
 }
 void update(int i, int val)
 {
  update_segment_tree(_value, 0, 0, _right_end, i, val);
 }
 int sumRange(int i, int j)
 {
  return sum_range_segment_tree(_value, 0, 0, _right_end, i, j);
 }
private:
 std::vector<int> _value;
 int _right_end;
};
int main()
{
 std::vector<int> nums;
 nums.push_back(1);
 nums.push_back(3);
 nums.push_back(5);
 NumArray num_array(nums);
 printf("%d\n",num_array.sumRange(0,2));
 num_array.update(1, 2);
 printf("%d\n", num_array.sumRange(0,2));
 return 0;
}

运行结果为:

9
8
发布了135 篇原创文章 · 获赞 121 · 访问量 4882

猜你喜欢

转载自blog.csdn.net/weixin_44208324/article/details/105202255