/** * The Binary Indexed Tree. */publicclassBIT{// The original array, which is not really necessary.privateint[]nums;// the size of the Binary Indexed array, size = n + 1, n is the length of original array.privateintsize;// The Binary Indexed Array, valid data are in [1, size), where size = n + 1// Original array element [i] is mapped to [i + 1] in the tree.privateint[]tree;publicBIT(int[]nums){this.nums=nums;size=nums.length+1;tree=newint[size];for(inti=0;i<size-1;i++){add(i+1,nums[i]);}}privatestaticintlowbit(inti){returni&-i;}// Update array element [i] to val// Meaning set nums[i] to val, but it is easier to maintain tree with delta// nums[i] = val, is the same to nums[i] = nums[i] + (val - nums[i]), where val - nums[i]// is the delta.// So we add affected items in tree with the delta.publicvoidupdate(inti,intval){add(i+1,val-nums[i]);nums[i]=val;}privatevoidadd(inti,intx){for(intj=i;j<size;j+=lowbit(j)){tree[j]+=x;}}// Query the regional sum in [l, r]publicintquery(intl,intr){returnpreSum(r+1)-preSum(l);}// Get the preSum up to i inclusive.privateintpreSum(inti){intsum=0;for(intj=i;j>0;j-=lowbit(j)){sum+=tree[j];}returnsum;}publicstaticvoidmain(String[]args){int[]a={1,2,3,4,5,6,7,8,9};BITbit=newBIT(a);System.out.println("3 = "+bit.query(0,1));System.out.println("18 = "+bit.query(2,5));bit.update(3,5);System.out.println("3 = "+bit.query(0,1));System.out.println("19 = "+bit.query(2,5));}}
/** * The Binary Indexed Tree * Support point query (PQ) and range update (RU) in O(log^n) complexity. */publicclassPQRUBIT{privateint[]tree;privateintsize;publicPQRUBIT(int[]nums){intn=nums.length;size=n+1;int[]diff=newint[n];tree=newint[size];diff[0]=nums[0];for(inti=1;i<n;i++){diff[i]=nums[i]-nums[i-1];}for(inti=0;i<size-1;i++){add(i+1,diff[i]);}}privatevoidadd(inti,intx){for(intj=i;j<size;j+=lowbit(j)){tree[j]+=x;}}privateintlowbit(inti){returni&-i;}publicintquery(inti){intres=0;for(intj=i+1;j>0;j-=lowbit(j)){res+=tree[j];}returnres;}publicvoidupdate(intl,intr,intx){add(l+1,x);add(r+2,-x);}publicstaticvoidmain(String[]args){int[]a={1,2,3,4,5,6,7,8,9};PQRUBITbit=newPQRUBIT(a);System.out.println("1 = "+bit.query(0));System.out.println("5 = "+bit.query(4));bit.update(2,5,3);System.out.println("1 = "+bit.query(0));System.out.println("6 = "+bit.query(2));System.out.println("8 = "+bit.query(4));System.out.println("9 = "+bit.query(5));System.out.println("7 = "+bit.query(6));}}
/** * The Binary Indexed Tree * Support range query (RQ) and range update (RU) in O(log^n) complexity. */publicclassRQRUBIT{privateintsize;privateint[]tree;privateint[]conTree;publicRQRUBIT(int[]nums){finalintn=nums.length;size=n+1;int[]diff=newint[n];diff[0]=nums[0];for(inti=1;i<n;i++){diff[i]=nums[i]-nums[i-1];}tree=newint[size];for(inti=0;i<n;i++){add(tree,i+1,diff[i]);}conTree=newint[size];for(inti=0;i<n;i++){add(conTree,i+1,i*diff[i]);}}publicintrangeQuery(intl,intr){intpreSumL=l*query(tree,l)-query(conTree,l);intpreSumR=(r+1)*query(tree,r+1)-query(conTree,r+1);returnpreSumR-preSumL;}publicvoidrangeUpdate(intl,intr,intx){add(tree,l+1,x);add(tree,r+2,-x);add(conTree,l+1,l*x);add(conTree,r+2,(r+1)*-x);}privatevoidadd(int[]t,inti,intx){for(intj=i;j<size;j+=lowbit(j)){t[j]+=x;}}privateintquery(int[]t,intk){intres=0;for(intj=k;j>0;j-=lowbit(j)){res+=t[j];}returnres;}privateintlowbit(inti){returni&-i;}publicstaticvoidmain(String[]args){int[]a={1,2,3,4,5,6,7,8,9};RQRUBITbit=newRQRUBIT(a);System.out.println("3 = "+bit.rangeQuery(0,1));System.out.println("18 = "+bit.rangeQuery(2,5));bit.rangeUpdate(3,6,3);System.out.println("3 = "+bit.rangeQuery(0,1));System.out.println("27 = "+bit.rangeQuery(2,5));System.out.println("10 = "+bit.rangeQuery(2,3));}}