1 class NumArray {
2 int MAXN;
3 int[] sum;
4 int[] arr;
5
6 public NumArray(int[] nums) {
7 this.arr = nums;
8 MAXN = nums.length << 2;//4倍空间
9 sum = new int[MAXN];
10 build(0, arr.length - 1, 1);
11 }
12
13 private void build(int l, int r, int rt) {
14 if (l == r) {
15 sum[rt] = arr[l];
16 return;
17 }
18 int mid = l + ((r - l) >> 1);
19 build(l, mid, rt << 1);
20 build(mid + 1, r, rt << 1 | 1);
21 pushUp(rt, rt << 1, rt << 1 | 1);
22 }
23
24 private void pushUp(int rt, int lc, int rc) {
25 sum[rt] = sum[lc] + sum[rc];
26 }
27
28 //nums[index] to val,本题只有单个位置的更新,所以不用维护更新表
29 public void update(int index, int val) {
30 update(index, index, val, 0, arr.length - 1, 1);
31 }
32
33 private void update(int l, int r, int C, int L, int R, int rt) {
34 if (l <= L && r >= R) {//必定是l==L==R==r
35 sum[rt] = C;
36 return;
37 }
38 //下发任务
39 int mid = L + ((R - L) >> 1);
40 if (l <= mid) {
41 update(l, r, C, L, mid, rt << 1);
42 }
43 if (r > mid) {
44 update(l, r, C, mid + 1, R, rt << 1 | 1);
45 }
46 pushUp(rt, rt << 1, rt << 1 | 1);
47 }
48
49
50 public int sumRange(int left, int right) {
51 return query(left, right, 0, arr.length - 1, 1);
52 }
53
54 private int query(int l, int r, int L, int R, int rt) {
55 if (l <= L && r >= R) {
56 return sum[rt];
57 }
58 //任务下发
59 int mid = L + ((R - L) >> 1);
60 int ans = 0;
61 if (l <= mid) {
62 ans += query(l, r, L, mid, rt << 1);
63 }
64 if (r > mid) {
65 ans += query(l, r, mid + 1, R, rt << 1 | 1);
66 }
67 pushUp(rt,rt<<1,rt<<1|1);//沿途没有懒着的任务,所以每次更新完整个线段树所有节点的值都是正确的,这里都不用pushUp了
68 return ans;
69 }
70 }
71
72 /**
73 * Your NumArray object will be instantiated and called as such:
74 * NumArray obj = new NumArray(nums);
75 * obj.update(index,val);
76 * int param_2 = obj.sumRange(left,right);
77 */