Given an integer array nums, find the sum of the elements between indices i and j (i ≤ j), inclusive.

The update(i, val) function modifies nums by updating the element at index i to val.

Example:

Given nums = [1, 3, 5]

sumRange(0, 2) -> 9
update(1, 2)
sumRange(0, 2) -> 8

Note:

  1. The array is only modifiable by the update function.
  2. You may assume the number of calls to update and sumRange function is distributed evenly
public class NumArray {
private SegmentTreeNode root = null;
private int size = 0; public NumArray(int[] nums) {
root = buildInSegmentTree(nums, 0, nums.length - 1);
size = nums.length;
} void update(int i, int val) {
if(i<0 || i>=size) return;
updateInSegmentTree(root, i, val);
} public int sumRange(int i, int j) {
if(i>j || i<0 || j>=size) return -1;
return querySum(root, i, j);
} class SegmentTreeNode{
int lc = 0, rc = 0, sum = 0;
SegmentTreeNode left = null, right = null;
SegmentTreeNode(int l, int r, int val) {
lc = l; rc = r; sum = val;
}
} public SegmentTreeNode buildInSegmentTree(int []nums, int l, int r) {
if(l > r) return null; if(l == r) {
SegmentTreeNode leaf = new SegmentTreeNode(l, r, nums[l]);
return leaf;
} SegmentTreeNode root = new SegmentTreeNode(l, r, 0);
int mid = (l + r) >> 1;
root.left = buildInSegmentTree(nums, l, mid);
root.right = buildInSegmentTree(nums, mid+1, r);
root.sum = root.left.sum + root.right.sum; return root;
} public void updateInSegmentTree(SegmentTreeNode root, int i, int val) {
if(root.lc == root.rc && root.lc == i) {
root.sum = val;
return;
} int mid = (root.lc + root.rc) >> 1;
if(i >= root.lc && i <= mid) updateInSegmentTree(root.left, i, val);
else updateInSegmentTree(root.right, i, val);
root.sum = root.left.sum + root.right.sum;
} public int querySum(SegmentTreeNode root, int i, int j) {
if(root.lc == i && root.rc == j) return root.sum; int mid = (root.lc + root.rc) >> 1;
if(i <= mid && j <= mid) return querySum(root.left, i, j);
else if(i > mid && j > mid) return querySum(root.right, i, j);
else return querySum(root.left, i, mid) + querySum(root.right, mid+1, j);
}
} // Your NumArray object will be instantiated and called as such:
// NumArray numArray = new NumArray(nums);
// numArray.sumRange(0, 1);
// numArray.update(1, 10);
// numArray.sumRange(1, 2);

下面附上java版segmentTree模板代码(共有两个文件:一个是SegmentTreeNode.java,另一个是SegmentTree.java。)

package cc150;

public class SegmentTreeNode {
public int lc, rc, sum, add;
SegmentTreeNode left, right; public SegmentTreeNode() {
this.lc = 0; this.rc = 0; this.sum = 0; this.add = 0;
this.left = null; this.right = null;
} public SegmentTreeNode(int l, int r, int val) {
this.lc = l; this.rc = r; this.sum = val; this.add = 0;
this.left = null; this.right = null;
} public static void main(String[] args) {
// TODO Auto-generated method stub } }

SegmentTreeNode.java

package cc150;

public class SegmentTree {
public SegmentTreeNode root = null;
int lower_bound, upper_bound; public SegmentTree() {
this.root = null;
this.lower_bound = 0; this.upper_bound = 0;
} public SegmentTree(int l, int r, int []nums) {
//@ SegmentTreeNode(left_idx, right_idx, sum).
this.root = new SegmentTreeNode(l, r, 0);
this.lower_bound = l; this.upper_bound = r;
buildSegmentTree(l, r, nums, root);
} public void buildSegmentTree(int l, int r, int []nums, SegmentTreeNode s) {
SegmentTreeNode sroot = s;
if(l > r) return; if(l == r) {
sroot.sum = nums[l];
return;
} int mid = (l + r) / 2;
sroot.left = new SegmentTreeNode(l, mid, 0);
buildSegmentTree(l, mid, nums, sroot.left); sroot.right = new SegmentTreeNode(mid+1, r, 0);
buildSegmentTree(mid+1, r, nums, sroot.right); sroot.sum = sroot.left.sum + sroot.right.sum; } public void updateByPoint(SegmentTreeNode sroot, int idx, int val) {
if(idx == sroot.lc && sroot.lc == sroot.rc) {
sroot.sum = val;
return;
} int mid = (sroot.lc + sroot.rc) / 2;
if(idx <= mid) updateByPoint(sroot.left, idx, val);
else updateByPoint(sroot.right, idx, val); sroot.sum = sroot.left.sum + sroot.right.sum;
} public void updateBySegment(SegmentTreeNode sroot, int l, int r, int val) {
if(l == sroot.lc && r == sroot.rc) {
sroot.add += val;
sroot.sum += val * (r - l + 1);
return;
} if(sroot.lc == sroot.rc) return;
int len = sroot.rc - sroot.lc + 1;
if(sroot.add > 0) {
sroot.left.add += sroot.add;
sroot.right.add += sroot.add;
sroot.left.sum += sroot.add * (len - (len/2));
sroot.right.sum += sroot.add * (len/2);
sroot.add = 0;
} int mid = sroot.lc + (sroot.rc - sroot.lc)/2;
if(r <= mid) updateBySegment(sroot.left, l, r, val);
else if(l > mid) updateBySegment(sroot.right, l, r, val);
else {
updateBySegment(sroot.left, l, mid, val);
updateBySegment(sroot.right, mid+1, r, val);
} sroot.sum = sroot.left.sum + sroot.right.sum;
} static int querySum(SegmentTreeNode sroot, int i, int j) {
if(i > j) {
System.out.println("Invalid Query!");
return -1;
}
if(i<sroot.lc || j>sroot.rc) return querySum(sroot, sroot.lc, sroot.rc); if(sroot.lc == i && sroot.rc == j) return sroot.sum;/*
int len = sroot.rc - sroot.lc + 1;
if(sroot.add > 0) {
sroot.left.add += sroot.add;
sroot.right.add += sroot.add;
sroot.left.sum += sroot.add * (len - len/2);
sroot.right.sum += sroot.add * (len/2);
sroot.add = 0;
}
*/
int mid = (sroot.lc + sroot.rc) / 2; if(j <= mid) return querySum(sroot.left, i, j);
else if(i > mid) return querySum(sroot.right, i, j);
else return querySum(sroot.left, i, mid) + querySum(sroot.right, mid+1, j);
} public static void main(String[] args) {
// TODO Auto-generated method stub
int []nums = new int[10];
for(int i=0;i<nums.length;++i) nums[i] = i; SegmentTree st = new SegmentTree(0, nums.length-1, nums);
int tmp = querySum(st.root, 0, 9);
System.out.println(tmp); st.updateByPoint(st.root, 5, 7);
System.out.println(querySum(st.root, 0, 9)); st.updateBySegment(st.root, 3, 4, 2);
System.out.println(querySum(st.root, 2, 7));
} }

SegmentTree.java

leetcode@ [307] Range Sum Query - Mutable / 线段树模板的更多相关文章

  1. [LeetCode] 307. Range Sum Query - Mutable 区域和检索 - 可变

    Given an integer array nums, find the sum of the elements between indices i and j (i ≤ j), inclusive ...

  2. [LeetCode] 307. Range Sum Query - Mutable 解题思路

    Given an integer array nums, find the sum of the elements between indices i and j (i ≤ j), inclusive ...

  3. LeetCode - 307. Range Sum Query - Mutable

    Given an integer array nums, find the sum of the elements between indices i and j (i ≤ j), inclusive ...

  4. leetcode 307. Range Sum Query - Mutable(树状数组)

    Given an integer array nums, find the sum of the elements between indices i and j (i ≤ j), inclusive ...

  5. Leetcode 2——Range Sum Query - Mutable(树状数组实现)

    Problem: Given an integer array nums, find the sum of the elements between indices i and j (i ≤ j), ...

  6. 【刷题-LeetCode】307. Range Sum Query - Mutable

    Range Sum Query - Mutable Given an integer array nums, find the sum of the elements between indices ...

  7. [Leetcode Week16]Range Sum Query - Mutable

    Range Sum Query - Mutable 题解 原创文章,拒绝转载 题目来源:https://leetcode.com/problems/range-sum-query-mutable/de ...

  8. 【leetcode】307. Range Sum Query - Mutable

    题目如下: 解题思路:就三个字-线段树.这个题目是线段树用法最经典的场景. 代码如下: class NumArray(object): def __init__(self, nums): " ...

  9. 307. Range Sum Query - Mutable

    题目: Given an integer array nums, find the sum of the elements between indices i and j (i ≤ j), inclu ...

随机推荐

  1. Spark中shuffle的触发和调度

    Spark中的shuffle是在干嘛? Shuffle在Spark中即是把父RDD中的KV对按照Key重新分区,从而得到一个新的RDD.也就是说原本同属于父RDD同一个分区的数据需要进入到子RDD的不 ...

  2. IIC驱动分析

    IIC设备是一种通过IIC总线连接的设备,由于其简单性,被广泛引用于电子系统中.在现代电子系统中,有很多的IIC设备需要进行相互之间通信 IIC总线是由PHILIPS公司开发的两线式串行总线,用于连接 ...

  3. Emoji表情符号兼容方案(适用ios,android,wp等平台)

    http://blog.csdn.net/qdkfriend/article/details/7576524 Emoji表情符号兼容方案 一 什么是Emoji emoji就是表情符号:词义来自日语(え ...

  4. hdu 4658 Integer Partition

    五角数定理!!可以参考这个http://www.cnblogs.com/xin-hua/p/3242428.html  代码如下: #include<iostream> #include& ...

  5. 198. House Robber

    题目: You are a professional robber planning to rob houses along a street. Each house has a certain am ...

  6. P163、面试题29:数组中出现次数超过一半的数字

    题目:数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2. 思 ...

  7. php 23种设计模式的趣味解释

    http://wenku.baidu.com/link?url=GwvuvSOdJneZQc-DSKoGmPcxTtzn3cdtIp3fRaCNbkg1zJDZZZTx2NwEK5IsqU996fG3 ...

  8. 在安装ISE的情况下,充分利用ISE的安装目录,查找资料

    2013-06-22 11:03:02 在找资料时,通过官网输入关键字的方法找资料,有事会给出很多版本的链接.或者找不到,下面给出一种简便的方法,可以快速找到想要的资料. 如果要找ISE各个工具如pl ...

  9. UVa 1644 (筛素数 + 二分) Prime Gap

    题意: 给出一个整数n,如果n是素数输出0,否则输出它后一个素数与前一个素数的差值. 分析: 首先用筛法把前十万个素数都筛出来,然后放到数组里.用二分找到不大于n的最大的素数的下标,如果这个素数等于n ...

  10. Nginx SPDY缓冲区溢出漏洞

    漏洞版本: nginx 1.3.15 nginx 1.5.x 漏洞描述: CVE ID:CVE-2014-0133 Nginx是HTTP及反向代理服务器,同时也用作邮件代理服务器,由Igor Syso ...