Binary Indexed Trees--树状数组

1 x&(-x) gives the last set bit in a number x. How?

Let’s say x = a1b(in binary) is the number whose last set bit we want to isolate.

Here a is some binary sequence of any length of 1’s and 0’s and b is some sequence of any length but of 0’s only. Remember we said we want the LAST set bit, so for that tiny intermediate 1 bit sitting between a and b to be the last set bit, b should be a sequence of 0’s only of length zero or more.

-x = 2’s complement of x = (a1b)’ + 1 = a’0b’ + 1 = a’0(0….0)’ + 1 = a’0(1...1) + 1 = a’1(0…0) = a’1b

Java代码:

    int[] bitTree;

    int lowbit(int x) {
        return x&(-x);
    }

    public void constructTree(int[] nums) {
        bitTree= new int[nums.length+1];

        // Store the actual values in BITree[] using update()
        for (int i=0; i<nums.length; i++)
            updateBIT(i, nums[i]);
    }

   //update operation takes at most O(log2(n)) time.
    public void updateBIT(int index, int val) {
        // index in bitTree[] is 1 more than the index in arr[]
        index = index + 1;

        // Traverse all ancestors and add 'val'
        while (index < bitTree.length) {
            //Add 'val' to current node of BI Tree
            bitTree[index] += val;

            //Update index to that of parent in update View
            index += lowbit(index);
        }
    }


    /**
     * Returns sum of arr[0..index]. This function assumes
     * that the array is preprocessed and partial sums of
     * array elements are stored
     */
    int read(int index) {
        int sum = 0; // Iniialize result

        // index in BITree[] is 1 more than the index in arr[]
        index = index + 1;

        // Traverse ancestors of BITree[index]
        while (index>0) {
            // Add current element of BITree to sum
            sum += bitTree[index];

            // Move index to parent node in getSum View
            index -= lowbit(index);
        }
        return sum;
    }

Range Sum Query - Mutable

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.

Given nums = [1, 3, 5]

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

使用上面树状数组的实现:

void update(int[] nums,int i, int val) {
    int diff = val - nums[i];
    nums[i] = val;
    updateBIT(i,diff);
}

int sumRange(int i, int j) {
  return read(j) - read(i-1);
}

References:

results matching ""

    No results matching ""