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 on index i to Val.
Example:
Given nums = [1, 3, 5]sumrange (0, 2), 9update (1, 2) sumrange (0, 2), 8
Note:
- The array is a modifiable by the update function.
- Assume the number of calls to update and sumrange function is distributed evenly
Public classNumarray {PrivateSegmenttreenode root =NULL; Private intSize = 0; PublicNumarray (int[] nums) {Root= Buildinsegmenttree (nums, 0, Nums.length-1); Size=nums.length; } voidUpdateintIintval) { if(i<0 | | i>=size)return; Updateinsegmenttree (Root, I, Val); } Public intSumrange (intIintj) {if(i>j | | i<0 | | j>=size)return-1; returnquerysum (Root, I, j); } classsegmenttreenode{intLC = 0, rc = 0, sum = 0; Segmenttreenode Left=NULL, right =NULL; Segmenttreenode (intLintRintval) {LC= L; rc = r; sum =Val; } } PublicSegmenttreenode Buildinsegmenttree (int[]nums,intLintr) {if(L > R)return NULL; if(L = =r) {Segmenttreenode leaf=NewSegmenttreenode (L, R, Nums[l]); returnLeaf; } Segmenttreenode Root=NewSegmenttreenode (l, R, 0); intMid = (L + r) >> 1; Root.left=Buildinsegmenttree (Nums, L, mid); Root.right= Buildinsegmenttree (Nums, mid+1, R); Root.sum= Root.left.sum +root.right.sum; returnRoot; } Public voidUpdateinsegmenttree (Segmenttreenode root,intIintval) { if(ROOT.LC = = Root.rc && ROOT.LC = =i) {root.sum=Val; return; } intMid = (root.lc + root.rc) >> 1; if(I >= root.lc && i <=mid) Updateinsegmenttree (Root.left, I, Val); ElseUpdateinsegmenttree (Root.right, I, Val); Root.sum= Root.left.sum +root.right.sum; } Public intQuerysum (Segmenttreenode root,intIintj) {if(ROOT.LC = = I && root.rc = = j)returnroot.sum; intMid = (root.lc + root.rc) >> 1; if(I <= Mid && J <= mid)returnquerysum (Root.left, I, J); Else if(I > Mid && J > mid)returnquerysum (Root.right, I, J); Else returnQuerysum (Root.left, I, mid) + querysum (root.right, mid+1, J); }}//Your Numarray object would be instantiated and called as such://Numarray Numarray = new Numarray (nums);//numarray.sumrange (0, 1);//numarray.update (1, ten);//Numarray.sumrange (1, 2);
View Code
The following is a Java version of the Segmenttree template code (total two files: one is Segmenttreenode.java, the other is Segmenttree.java. )
Packagecc150; Public classSegmenttreenode { Public intLC, RC, sum, add; Segmenttreenode left, right; PublicSegmenttreenode () { This. LC = 0; This. rc = 0; This. sum = 0; This. Add = 0; This. left =NULL; This. right =NULL; } PublicSegmenttreenode (intLintRintval) { This. LC = L; This. rc = r; This. sum = val; This. Add = 0; This. left =NULL; This. right =NULL; } Public Static voidMain (string[] args) {//TODO auto-generated Method Stub }}
Segmenttreenode.java
Packagecc150; Public classSegmenttree { PublicSegmenttreenode root =NULL; intLower_bound, Upper_bound; PublicSegmenttree () { This. root =NULL; This. lower_bound = 0; This. Upper_bound = 0; } PublicSegmenttree (intLintRint[]nums] { //@ segmenttreenode (left_idx, Right_idx, sum). This. root =NewSegmenttreenode (l, R, 0); This. Lower_bound = l; This. Upper_bound =R; Buildsegmenttree (L, R, Nums, root); } Public voidBuildsegmenttree (intLintRint[]nums, Segmenttreenode S] {Segmenttreenode Sroot=s; if(L > R)return; if(L = =r) {sroot.sum=Nums[l]; return; } intMid = (L + r)/2; Sroot.left=NewSegmenttreenode (l, Mid, 0); Buildsegmenttree (L, Mid, Nums, sroot.left); Sroot.right=NewSegmenttreenode (mid+1, R, 0); Buildsegmenttree (Mid+1, R, Nums, Sroot.right); Sroot.sum= Sroot.left.sum +sroot.right.sum; } Public voidUpdatebypoint (Segmenttreenode Sroot,intIdxintval) { if(idx = = SROOT.LC && SROOT.LC = =sroot.rc) {sroot.sum=Val; return; } intMid = (sroot.lc + sroot.rc)/2; if(IDX <=mid) Updatebypoint (Sroot.left, IDX, Val); Elseupdatebypoint (Sroot.right, IDX, Val); Sroot.sum= Sroot.left.sum +sroot.right.sum; } Public voidUpdatebysegment (Segmenttreenode Sroot,intLintRintval) { if(L = = Sroot.lc && r = =sroot.rc) {Sroot.add+=Val; Sroot.sum+ = Val * (r-l + 1); return; } if(SROOT.LC = = sroot.rc)return; intLen = 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; } intMID = 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 intQuerysum (Segmenttreenode Sroot,intIintj) {if(I >j) {System.out.println ("Invalid query!"); return-1; } if(I<SROOT.LC | | j>sroot.rc)returnquerysum (Sroot, SROOT.LC, sroot.rc); if(SROOT.LC = = I && sroot.rc = = j)returnSroot.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; } */ intMid = (sroot.lc + sroot.rc)/2; if(J <= Mid)returnquerysum (Sroot.left, I, J); Else if(I > Mid)returnquerysum (Sroot.right, I, J); Else returnQuerysum (Sroot.left, I, mid) + querysum (sroot.right, mid+1, J); } Public Static voidMain (string[] args) {//TODO auto-generated Method Stub int[]nums =New int[10]; for(intI=0;i<nums.length;++i) Nums[i] =i; Segmenttree St=NewSegmenttree (0, Nums.length-1, Nums); intTMP = 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
[email protected] [307] Range Sum query-mutable/segment Tree template