📌  相关文章
📜  二进制索引树:范围更新和点查询

📅  最后修改于: 2021-04-17 11:09:08             🧑  作者: Mango

给定一个数组arr [0..n-1]。需要执行以下操作。

  1. update(l,r,val) :将[val]从[l,r]添加到数组中的所有元素。
  2. getElement(i) :在索引为“ i”的数组中查找元素。

    最初,数组中的所有元素均为0。查询可以按任何顺序进行,即,在点查询之前可以进行许多更新。

    例子:

    Input : arr = {0, 0, 0, 0, 0}
    Queries: update : l = 0, r = 4, val = 2
             getElement : i = 3
             update : l = 3, r = 4, val = 3 
             getElement : i = 3
    
    Output: Element at 3 is 2
            Element at 3 is 5
     
    Explanation : Array after first update becomes
                  {2, 2, 2, 2, 2}
                  Array after second update becomes
                  {2, 2, 2, 5, 5}
    

    方法1 [更新:O(n),getElement():O(1)]

    1. update(l,r,val):从l到r遍历子数组,并将所有元素增加val。
    2. getElement(i) :要获取第i个索引的元素,只需返回arr [i]。

    最坏情况下的时间复杂度为O(q * n),其中q是查询数,n是元素数。

    方法2 [更新:O(1),getElement():O(n)]

    我们可以避免更新所有元素,并且只能更新数组的2个索引!

    1. update(l,r,val):在第l元素中添加“ val”,并从第(r + 1)元素中减去“ val”,针对所有更新查询执行此操作。
      arr[l]   = arr[l] + val
        arr[r+1] = arr[r+1] - val 
      
    2. getElement(i) :要获取数组中的i元素,请找到数组中所有从0到i的整数的和。(前缀和)。

    让我们分析一下更新查询。为什么要在l索引上添加val?l索引添加val意味着l之后的所有元素都将增加val,因为我们将为每个元素计算前缀和。为什么要从第(r + 1)索引中减去val?需要从[l,r]进行范围更新,但是我们更新的是[l,n-1],因此我们需要从r之后的所有元素中删除val,即从第(r + 1)索引中减去val。因此,将val添加到范围[l,r]。下面是上述方法的实现。

    C++
    // C++ program to demonstrate Range Update 
    // and Point Queries Without using BIT 
    #include  
    using namespace std; 
      
    // Updates such that getElement() gets an increased 
    // value when queried from l to r. 
    void update(int arr[], int l, int r, int val) 
    { 
        arr[l] += val; 
        arr[r+1] -= val; 
    } 
      
    // Get the element indexed at i 
    int getElement(int arr[], int i) 
    { 
        // To get ith element sum of all the elements 
        // from 0 to i need to be computed 
        int res = 0; 
        for (int j = 0 ; j <= i; j++) 
            res += arr[j]; 
      
        return res; 
    } 
      
    // Driver program to test above function 
    int main() 
    { 
        int arr[] = {0, 0, 0, 0, 0}; 
        int n = sizeof(arr) / sizeof(arr[0]); 
      
        int l = 2, r = 4, val = 2; 
        update(arr, l, r, val); 
      
        //Find the element at Index 4 
        int index = 4; 
        cout << "Element at index " << index << " is " << 
             getElement(arr, index) << endl; 
      
        l = 0, r = 3, val = 4; 
        update(arr,l,r,val); 
      
        //Find the element at Index 3 
        index = 3; 
        cout << "Element at index " << index << " is " << 
             getElement(arr, index) << endl; 
      
        return 0; 
    }


    Java
    // Java program to demonstrate Range Update 
    // and Point Queries Without using BIT 
    class GfG { 
      
    // Updates such that getElement() gets an increased 
    // value when queried from l to r. 
    static void update(int arr[], int l, int r, int val) 
    { 
        arr[l] += val;
        if(r + 1 < arr.length)
        arr[r+1] -= val; 
    } 
      
    // Get the element indexed at i 
    static int getElement(int arr[], int i) 
    { 
        // To get ith element sum of all the elements 
        // from 0 to i need to be computed 
        int res = 0; 
        for (int j = 0 ; j <= i; j++) 
            res += arr[j]; 
      
        return res; 
    } 
      
    // Driver program to test above function 
    public static void main(String[] args) 
    { 
        int arr[] = {0, 0, 0, 0, 0}; 
        int n = arr.length; 
      
        int l = 2, r = 4, val = 2; 
        update(arr, l, r, val); 
      
        //Find the element at Index 4 
        int index = 4; 
        System.out.println("Element at index " + index + " is " +getElement(arr, index)); 
      
        l = 0;
        r = 3;
        val = 4; 
        update(arr,l,r,val); 
      
        //Find the element at Index 3 
        index = 3; 
        System.out.println("Element at index " + index + " is " +getElement(arr, index)); 
      
    }
    }


    Python3
    # Python3 program to demonstrate Range 
    # Update and PoQueries Without using BIT 
      
    # Updates such that getElement() gets an 
    # increased value when queried from l to r. 
    def update(arr, l, r, val):
        arr[l] += val
        if r + 1 < len(arr):
            arr[r + 1] -= val
      
    # Get the element indexed at i 
    def getElement(arr, i):
          
        # To get ith element sum of all the elements 
        # from 0 to i need to be computed 
        res = 0
        for j in range(i + 1):
            res += arr[j] 
      
        return res
      
    # Driver Code
    if __name__ == '__main__': 
        arr = [0, 0, 0, 0, 0] 
        n = len(arr) 
      
        l = 2
        r = 4
        val = 2
        update(arr, l, r, val) 
      
        # Find the element at Index 4 
        index = 4
        print("Element at index", index, 
              "is", getElement(arr, index)) 
      
        l = 0
        r = 3
        val = 4
        update(arr, l, r, val) 
      
        # Find the element at Index 3 
        index = 3
        print("Element at index", index,
              "is", getElement(arr, index))
      
    # This code is contributed by PranchalK


    C#
    // C# program to demonstrate Range Update 
    // and Point Queries Without using BIT 
    using System;
      
    class GfG 
    { 
      
    // Updates such that getElement() 
    // gets an increased value when
    // queried from l to r. 
    static void update(int []arr, int l, 
                        int r, int val) 
    { 
        arr[l] += val; 
        if(r + 1 < arr.Length) 
        arr[r + 1] -= val; 
    } 
      
    // Get the element indexed at i 
    static int getElement(int []arr, int i) 
    { 
        // To get ith element sum of all the elements 
        // from 0 to i need to be computed 
        int res = 0; 
        for (int j = 0 ; j <= i; j++) 
            res += arr[j]; 
      
        return res; 
    } 
      
    // Driver code 
    public static void Main(String[] args) 
    { 
        int []arr = {0, 0, 0, 0, 0}; 
        int n = arr.Length; 
      
        int l = 2, r = 4, val = 2; 
        update(arr, l, r, val); 
      
        //Find the element at Index 4 
        int index = 4; 
        Console.WriteLine("Element at index " + 
                            index + " is " +
                            getElement(arr, index)); 
      
        l = 0; 
        r = 3; 
        val = 4; 
        update(arr,l,r,val); 
      
        //Find the element at Index 3 
        index = 3; 
        Console.WriteLine("Element at index " + 
                                index + " is " +
                                getElement(arr, index)); 
    } 
    } 
      
    // This code is contributed by PrinciRaj1992


    PHP


    C++
    // C++ code to demonstrate Range Update and
    // Point Queries on a Binary Index Tree
    #include 
    using namespace std;
      
    // Updates a node in Binary Index Tree (BITree) at given index
    // in BITree. The given value 'val' is added to BITree[i] and
    // all of its ancestors in tree.
    void updateBIT(int BITree[], int n, int index, int val)
    {
        // index in BITree[] is 1 more than the index in arr[]
        index = index + 1;
      
        // Traverse all ancestors and add 'val'
        while (index <= n)
        {
            // Add 'val' to current node of BI Tree
            BITree[index] += val;
      
            // Update index to that of parent in update View
            index += index & (-index);
        }
    }
      
    // Constructs and returns a Binary Indexed Tree for given
    // array of size n.
    int *constructBITree(int arr[], int n)
    {
        // Create and initialize BITree[] as 0
        int *BITree = new int[n+1];
        for (int i=1; i<=n; i++)
            BITree[i] = 0;
      
        // Store the actual values in BITree[] using update()
        for (int i=0; i0)
        {
            // Add current element of BITree to sum
            sum += BITree[index];
      
            // Move index to parent node in getSum View
            index -= index & (-index);
        }
        return sum;
    }
      
    // Updates such that getElement() gets an increased
    // value when queried from l to r.
    void update(int BITree[], int l, int r, int n, int val)
    {
        // Increase value at 'l' by 'val'
        updateBIT(BITree, n, l, val);
      
        // Decrease value at 'r+1' by 'val'
        updateBIT(BITree, n, r+1, -val);
    }
      
    // Driver program to test above function
    int main()
    {
        int arr[] = {0, 0, 0, 0, 0};
        int n = sizeof(arr)/sizeof(arr[0]);
        int *BITree = constructBITree(arr, n);
      
        // Add 2 to all the element from [2,4]
        int l = 2, r = 4, val = 2;
        update(BITree, l, r, n, val);
      
        // Find the element at Index 4
        int index = 4;
        cout << "Element at index " << index << " is " <<
             getSum(BITree,index) << "\n";
      
        // Add 2 to all the element from [0,3]
        l = 0, r = 3, val = 4;
        update(BITree, l, r, n, val);
      
        // Find the element at Index 3
        index = 3;
        cout << "Element at index " << index << " is " <<
             getSum(BITree,index) << "\n" ;
      
        return 0;
    }


    Java
    /* Java code to demonstrate Range Update and
    * Point Queries on a Binary Index Tree.
    * This method only works when all array
    * values are initially 0.*/
    class GFG
    {
      
        // Max tree size
        final static int MAX = 1000;
      
        static int BITree[] = new int[MAX];
      
        // Updates a node in Binary Index
        // Tree (BITree) at given index
        // in BITree. The given value 'val'
        // is added to BITree[i] and
        // all of its ancestors in tree.
        public static void updateBIT(int n, 
                                     int index, 
                                     int val)
        {
            // index in BITree[] is 1 
            // more than the index in arr[]
            index = index + 1;
      
            // Traverse all ancestors 
            // and add 'val'
            while (index <= n)
            {
                // Add 'val' to current 
                // node of BITree
                BITree[index] += val;
      
                // Update index to that 
                // of parent in update View
                index += index & (-index);
            }
        }
      
        // Constructs Binary Indexed Tree 
        // for given array of size n.
      
        public static void constructBITree(int arr[],
                                           int n)
        {
            // Initialize BITree[] as 0
            for(int i = 1; i <= n; i++)
                BITree[i] = 0;
      
            // Store the actual values 
            // in BITree[] using update()
            for(int i = 0; i < n; i++)
                updateBIT(n, i, arr[i]);
      
            // Uncomment below lines to 
            // see contents of BITree[]
            // for (int i=1; i<=n; i++)
            //     cout << BITree[i] << " ";
        }
      
        // SERVES THE PURPOSE OF getElement()
        // Returns sum of arr[0..index]. This 
        // function assumes that the array is
        // preprocessed and partial sums of
        // array elements are stored in BITree[]
        public static int getSum(int index)
        {
            int sum = 0; //Initialize 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 += BITree[index];
      
                // Move index to parent 
                // node in getSum View
                index -= index & (-index);
            }
      
            // Return the sum
            return sum;
        }
      
        // Updates such that getElement() 
        // gets an increased value when 
        // queried from l to r.
        public static void update(int l, int r, 
                                  int n, int val)
        {
            // Increase value at 
            // 'l' by 'val'
            updateBIT(n, l, val);
      
            // Decrease value at
            // 'r+1' by 'val'
            updateBIT(n, r + 1, -val);
        }
      
      
        // Driver Code
        public static void main(String args[])
        {
            int arr[] = {0, 0, 0, 0, 0};
            int n = arr.length;
      
            constructBITree(arr,n);
      
            // Add 2 to all the
            // element from [2,4]
            int l = 2, r = 4, val = 2;
            update(l, r, n, val);
      
            int index = 4;
      
            System.out.println("Element at index "+ 
                                    index + " is "+ 
                                    getSum(index));
      
            // Add 2 to all the 
            // element from [0,3]
            l = 0; r = 3; val = 4;
            update(l, r, n, val);
      
            // Find the element
            // at Index 3
            index = 3;
            System.out.println("Element at index "+ 
                                    index + " is "+ 
                                    getSum(index));
        }
    }
    // This code is contributed
    // by Puneet Kumar.


    Python3
    # Python3 code to demonstrate Range Update and
    # PoQueries on a Binary Index Tree
      
    # Updates a node in Binary Index Tree (BITree) at given index
    # in BITree. The given value 'val' is added to BITree[i] and
    # all of its ancestors in tree.
    def updateBIT(BITree, n, index, val):
          
        # index in BITree[] is 1 more than the index in arr[]
        index = index + 1
      
        # Traverse all ancestors and add 'val'
        while (index <= n):
              
            # Add 'val' to current node of BI Tree
            BITree[index] += val
      
            # Update index to that of parent in update View
            index += index & (-index)
      
    # Constructs and returns a Binary Indexed Tree for given
    # array of size n.
    def constructBITree(arr, n):
          
        # Create and initialize BITree[] as 0
        BITree = [0]*(n+1)
      
        # Store the actual values in BITree[] using update()
        for i in range(n):
            updateBIT(BITree, n, i, arr[i])
      
        return BITree
      
    # SERVES THE PURPOSE OF getElement()
    # Returns sum of arr[0..index]. This function assumes
    # that the array is preprocessed and partial sums of
    # array elements are stored in BITree[]
    def getSum(BITree, index):
        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 += BITree[index]
      
            # Move index to parent node in getSum View
            index -= index & (-index)
        return sum
      
    # Updates such that getElement() gets an increased
    # value when queried from l to r.
    def update(BITree, l, r, n, val):
          
        # Increase value at 'l' by 'val'
        updateBIT(BITree, n, l, val)
      
        # Decrease value at 'r+1' by 'val'
        updateBIT(BITree, n, r+1, -val)
      
    # Driver code
    arr = [0, 0, 0, 0, 0]
    n = len(arr)
    BITree = constructBITree(arr, n)
      
    # Add 2 to all the element from [2,4]
    l = 2
    r = 4
    val = 2
    update(BITree, l, r, n, val)
      
    # Find the element at Index 4
    index = 4
    print("Element at index", index, "is", getSum(BITree, index))
      
    # Add 2 to all the element from [0,3]
    l = 0
    r = 3
    val = 4
    update(BITree, l, r, n, val)
      
    # Find the element at Index 3
    index = 3
    print("Element at index", index, "is", getSum(BITree,index))
      
    # This code is contributed by mohit kumar 29


    C#
    using System;
      
    /* C# code to demonstrate Range Update and 
    * Point Queries on a Binary Index Tree. 
    * This method only works when all array 
    * values are initially 0.*/
    public class GFG
    {
      
        // Max tree size 
        public const int MAX = 1000;
      
        public static int[] BITree = new int[MAX];
      
        // Updates a node in Binary Index 
        // Tree (BITree) at given index 
        // in BITree. The given value 'val' 
        // is added to BITree[i] and 
        // all of its ancestors in tree. 
        public static void updateBIT(int n, int index, int val)
        {
            // index in BITree[] is 1  
            // more than the index in arr[] 
            index = index + 1;
      
            // Traverse all ancestors  
            // and add 'val' 
            while (index <= n)
            {
                // Add 'val' to current  
                // node of BITree 
                BITree[index] += val;
      
                // Update index to that  
                // of parent in update View 
                index += index & (-index);
            }
        }
      
        // Constructs Binary Indexed Tree  
        // for given array of size n. 
      
        public static void constructBITree(int[] arr, int n)
        {
            // Initialize BITree[] as 0 
            for (int i = 1; i <= n; i++)
            {
                BITree[i] = 0;
            }
      
            // Store the actual values  
            // in BITree[] using update() 
            for (int i = 0; i < n; i++)
            {
                updateBIT(n, i, arr[i]);
            }
      
            // Uncomment below lines to  
            // see contents of BITree[] 
            // for (int i=1; i<=n; i++) 
            //     cout << BITree[i] << " "; 
        }
      
        // SERVES THE PURPOSE OF getElement() 
        // Returns sum of arr[0..index]. This  
        // function assumes that the array is 
        // preprocessed and partial sums of 
        // array elements are stored in BITree[] 
        public static int getSum(int index)
        {
            int sum = 0; //Initialize 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 += BITree[index];
      
                // Move index to parent  
                // node in getSum View 
                index -= index & (-index);
            }
      
            // Return the sum 
            return sum;
        }
      
        // Updates such that getElement()  
        // gets an increased value when  
        // queried from l to r. 
        public static void update(int l, int r, int n, int val)
        {
            // Increase value at  
            // 'l' by 'val' 
            updateBIT(n, l, val);
      
            // Decrease value at 
            // 'r+1' by 'val' 
            updateBIT(n, r + 1, -val);
        }
      
      
        // Driver Code 
        public static void Main(string[] args)
        {
            int[] arr = new int[] {0, 0, 0, 0, 0};
            int n = arr.Length;
      
            constructBITree(arr,n);
      
            // Add 2 to all the 
            // element from [2,4] 
            int l = 2, r = 4, val = 2;
            update(l, r, n, val);
      
            int index = 4;
      
            Console.WriteLine("Element at index " + index + " is " + getSum(index));
      
            // Add 2 to all the  
            // element from [0,3] 
            l = 0;
            r = 3;
            val = 4;
            update(l, r, n, val);
      
            // Find the element 
            // at Index 3 
            index = 3;
            Console.WriteLine("Element at index " + index + " is " + getSum(index));
        }
    }
      
      
      // This code is contributed by Shrikant13


    输出:

    Element at index 4 is 2
    Element at index 3 is 6
    

    时间复杂度:O(q * n),其中q是查询数。

    方法3(使用二进制索引树)

    在方法2中,我们已经看到该问题可以简化为更新和前缀和查询。我们已经看到,BIT可用于在O(Logn)时间内进行更新和前缀和查询。

    下面是实现。

    C++

    // C++ code to demonstrate Range Update and
    // Point Queries on a Binary Index Tree
    #include 
    using namespace std;
      
    // Updates a node in Binary Index Tree (BITree) at given index
    // in BITree. The given value 'val' is added to BITree[i] and
    // all of its ancestors in tree.
    void updateBIT(int BITree[], int n, int index, int val)
    {
        // index in BITree[] is 1 more than the index in arr[]
        index = index + 1;
      
        // Traverse all ancestors and add 'val'
        while (index <= n)
        {
            // Add 'val' to current node of BI Tree
            BITree[index] += val;
      
            // Update index to that of parent in update View
            index += index & (-index);
        }
    }
      
    // Constructs and returns a Binary Indexed Tree for given
    // array of size n.
    int *constructBITree(int arr[], int n)
    {
        // Create and initialize BITree[] as 0
        int *BITree = new int[n+1];
        for (int i=1; i<=n; i++)
            BITree[i] = 0;
      
        // Store the actual values in BITree[] using update()
        for (int i=0; i0)
        {
            // Add current element of BITree to sum
            sum += BITree[index];
      
            // Move index to parent node in getSum View
            index -= index & (-index);
        }
        return sum;
    }
      
    // Updates such that getElement() gets an increased
    // value when queried from l to r.
    void update(int BITree[], int l, int r, int n, int val)
    {
        // Increase value at 'l' by 'val'
        updateBIT(BITree, n, l, val);
      
        // Decrease value at 'r+1' by 'val'
        updateBIT(BITree, n, r+1, -val);
    }
      
    // Driver program to test above function
    int main()
    {
        int arr[] = {0, 0, 0, 0, 0};
        int n = sizeof(arr)/sizeof(arr[0]);
        int *BITree = constructBITree(arr, n);
      
        // Add 2 to all the element from [2,4]
        int l = 2, r = 4, val = 2;
        update(BITree, l, r, n, val);
      
        // Find the element at Index 4
        int index = 4;
        cout << "Element at index " << index << " is " <<
             getSum(BITree,index) << "\n";
      
        // Add 2 to all the element from [0,3]
        l = 0, r = 3, val = 4;
        update(BITree, l, r, n, val);
      
        // Find the element at Index 3
        index = 3;
        cout << "Element at index " << index << " is " <<
             getSum(BITree,index) << "\n" ;
      
        return 0;
    }
    

    Java

    /* Java code to demonstrate Range Update and
    * Point Queries on a Binary Index Tree.
    * This method only works when all array
    * values are initially 0.*/
    class GFG
    {
      
        // Max tree size
        final static int MAX = 1000;
      
        static int BITree[] = new int[MAX];
      
        // Updates a node in Binary Index
        // Tree (BITree) at given index
        // in BITree. The given value 'val'
        // is added to BITree[i] and
        // all of its ancestors in tree.
        public static void updateBIT(int n, 
                                     int index, 
                                     int val)
        {
            // index in BITree[] is 1 
            // more than the index in arr[]
            index = index + 1;
      
            // Traverse all ancestors 
            // and add 'val'
            while (index <= n)
            {
                // Add 'val' to current 
                // node of BITree
                BITree[index] += val;
      
                // Update index to that 
                // of parent in update View
                index += index & (-index);
            }
        }
      
        // Constructs Binary Indexed Tree 
        // for given array of size n.
      
        public static void constructBITree(int arr[],
                                           int n)
        {
            // Initialize BITree[] as 0
            for(int i = 1; i <= n; i++)
                BITree[i] = 0;
      
            // Store the actual values 
            // in BITree[] using update()
            for(int i = 0; i < n; i++)
                updateBIT(n, i, arr[i]);
      
            // Uncomment below lines to 
            // see contents of BITree[]
            // for (int i=1; i<=n; i++)
            //     cout << BITree[i] << " ";
        }
      
        // SERVES THE PURPOSE OF getElement()
        // Returns sum of arr[0..index]. This 
        // function assumes that the array is
        // preprocessed and partial sums of
        // array elements are stored in BITree[]
        public static int getSum(int index)
        {
            int sum = 0; //Initialize 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 += BITree[index];
      
                // Move index to parent 
                // node in getSum View
                index -= index & (-index);
            }
      
            // Return the sum
            return sum;
        }
      
        // Updates such that getElement() 
        // gets an increased value when 
        // queried from l to r.
        public static void update(int l, int r, 
                                  int n, int val)
        {
            // Increase value at 
            // 'l' by 'val'
            updateBIT(n, l, val);
      
            // Decrease value at
            // 'r+1' by 'val'
            updateBIT(n, r + 1, -val);
        }
      
      
        // Driver Code
        public static void main(String args[])
        {
            int arr[] = {0, 0, 0, 0, 0};
            int n = arr.length;
      
            constructBITree(arr,n);
      
            // Add 2 to all the
            // element from [2,4]
            int l = 2, r = 4, val = 2;
            update(l, r, n, val);
      
            int index = 4;
      
            System.out.println("Element at index "+ 
                                    index + " is "+ 
                                    getSum(index));
      
            // Add 2 to all the 
            // element from [0,3]
            l = 0; r = 3; val = 4;
            update(l, r, n, val);
      
            // Find the element
            // at Index 3
            index = 3;
            System.out.println("Element at index "+ 
                                    index + " is "+ 
                                    getSum(index));
        }
    }
    // This code is contributed
    // by Puneet Kumar.
    

    Python3

    # Python3 code to demonstrate Range Update and
    # PoQueries on a Binary Index Tree
      
    # Updates a node in Binary Index Tree (BITree) at given index
    # in BITree. The given value 'val' is added to BITree[i] and
    # all of its ancestors in tree.
    def updateBIT(BITree, n, index, val):
          
        # index in BITree[] is 1 more than the index in arr[]
        index = index + 1
      
        # Traverse all ancestors and add 'val'
        while (index <= n):
              
            # Add 'val' to current node of BI Tree
            BITree[index] += val
      
            # Update index to that of parent in update View
            index += index & (-index)
      
    # Constructs and returns a Binary Indexed Tree for given
    # array of size n.
    def constructBITree(arr, n):
          
        # Create and initialize BITree[] as 0
        BITree = [0]*(n+1)
      
        # Store the actual values in BITree[] using update()
        for i in range(n):
            updateBIT(BITree, n, i, arr[i])
      
        return BITree
      
    # SERVES THE PURPOSE OF getElement()
    # Returns sum of arr[0..index]. This function assumes
    # that the array is preprocessed and partial sums of
    # array elements are stored in BITree[]
    def getSum(BITree, index):
        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 += BITree[index]
      
            # Move index to parent node in getSum View
            index -= index & (-index)
        return sum
      
    # Updates such that getElement() gets an increased
    # value when queried from l to r.
    def update(BITree, l, r, n, val):
          
        # Increase value at 'l' by 'val'
        updateBIT(BITree, n, l, val)
      
        # Decrease value at 'r+1' by 'val'
        updateBIT(BITree, n, r+1, -val)
      
    # Driver code
    arr = [0, 0, 0, 0, 0]
    n = len(arr)
    BITree = constructBITree(arr, n)
      
    # Add 2 to all the element from [2,4]
    l = 2
    r = 4
    val = 2
    update(BITree, l, r, n, val)
      
    # Find the element at Index 4
    index = 4
    print("Element at index", index, "is", getSum(BITree, index))
      
    # Add 2 to all the element from [0,3]
    l = 0
    r = 3
    val = 4
    update(BITree, l, r, n, val)
      
    # Find the element at Index 3
    index = 3
    print("Element at index", index, "is", getSum(BITree,index))
      
    # This code is contributed by mohit kumar 29
    

    C#

    using System;
      
    /* C# code to demonstrate Range Update and 
    * Point Queries on a Binary Index Tree. 
    * This method only works when all array 
    * values are initially 0.*/
    public class GFG
    {
      
        // Max tree size 
        public const int MAX = 1000;
      
        public static int[] BITree = new int[MAX];
      
        // Updates a node in Binary Index 
        // Tree (BITree) at given index 
        // in BITree. The given value 'val' 
        // is added to BITree[i] and 
        // all of its ancestors in tree. 
        public static void updateBIT(int n, int index, int val)
        {
            // index in BITree[] is 1  
            // more than the index in arr[] 
            index = index + 1;
      
            // Traverse all ancestors  
            // and add 'val' 
            while (index <= n)
            {
                // Add 'val' to current  
                // node of BITree 
                BITree[index] += val;
      
                // Update index to that  
                // of parent in update View 
                index += index & (-index);
            }
        }
      
        // Constructs Binary Indexed Tree  
        // for given array of size n. 
      
        public static void constructBITree(int[] arr, int n)
        {
            // Initialize BITree[] as 0 
            for (int i = 1; i <= n; i++)
            {
                BITree[i] = 0;
            }
      
            // Store the actual values  
            // in BITree[] using update() 
            for (int i = 0; i < n; i++)
            {
                updateBIT(n, i, arr[i]);
            }
      
            // Uncomment below lines to  
            // see contents of BITree[] 
            // for (int i=1; i<=n; i++) 
            //     cout << BITree[i] << " "; 
        }
      
        // SERVES THE PURPOSE OF getElement() 
        // Returns sum of arr[0..index]. This  
        // function assumes that the array is 
        // preprocessed and partial sums of 
        // array elements are stored in BITree[] 
        public static int getSum(int index)
        {
            int sum = 0; //Initialize 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 += BITree[index];
      
                // Move index to parent  
                // node in getSum View 
                index -= index & (-index);
            }
      
            // Return the sum 
            return sum;
        }
      
        // Updates such that getElement()  
        // gets an increased value when  
        // queried from l to r. 
        public static void update(int l, int r, int n, int val)
        {
            // Increase value at  
            // 'l' by 'val' 
            updateBIT(n, l, val);
      
            // Decrease value at 
            // 'r+1' by 'val' 
            updateBIT(n, r + 1, -val);
        }
      
      
        // Driver Code 
        public static void Main(string[] args)
        {
            int[] arr = new int[] {0, 0, 0, 0, 0};
            int n = arr.Length;
      
            constructBITree(arr,n);
      
            // Add 2 to all the 
            // element from [2,4] 
            int l = 2, r = 4, val = 2;
            update(l, r, n, val);
      
            int index = 4;
      
            Console.WriteLine("Element at index " + index + " is " + getSum(index));
      
            // Add 2 to all the  
            // element from [0,3] 
            l = 0;
            r = 3;
            val = 4;
            update(l, r, n, val);
      
            // Find the element 
            // at Index 3 
            index = 3;
            Console.WriteLine("Element at index " + index + " is " + getSum(index));
        }
    }
      
      
      // This code is contributed by Shrikant13
    

    输出:

    Element at index 4 is 2
    Element at index 3 is 6
    

    时间复杂度: O(q * log n)+ O(n * log n)其中q是查询数。

    当大多数查询是getElement()时,方法1是有效的;当大多数查询是updates()时,方法2是有效的;当两个查询混合使用时,方法3是首选的。