バイナリ インデックス付きツリー : 範囲更新とポイント クエリ

配列 arr[0..n-1] を指定します。次の操作を実行する必要があります。

    update(l r val) : [l r] の配列内のすべての要素に 'val' を追加します。 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)]

    更新(l r val): 部分配列を l から r まで反復し、すべての要素を val だけ増やします。 getElement(i): i 番目のインデックスにある要素を取得するには、単純に arr[i] を返します。

最悪の場合の時間計算量は O(q*n) です。ここで、q はクエリの数、n は要素の数です。  

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

すべての要素の更新を回避でき、配列の 2 つのインデックスのみを更新できます。

    update(l r val) : l に「val」を追加します 番目 要素を計算し、(r+1) から「val」を減算します。 番目 要素では、すべての更新クエリに対してこれを実行します。
 arr[l] = arr[l] + val arr[r+1] = arr[r+1] - val 
    getElement(i) : 私を手に入れるために 番目 配列内の要素で、配列内の 0 から i までのすべての整数の合計を求めます (プレフィックス合計)。

更新クエリを分析してみましょう。 なぜ l に val を加えるのか 番目 索引? l に val を追加する 番目 index は、すべての要素の接頭辞の合計を計算するため、l 以降のすべての要素が val だけ増加することを意味します。 (r+1) から val を引く理由 番目 索引? [lr] から範囲の更新が必要でしたが、更新したのは [l n-1] なので、r の後のすべての要素から val を削除する必要があります。つまり、(r+1) から val を減算する必要があります。 番目 索引。したがって、val は範囲 [lr] に追加されます。以下は、上記のアプローチの実装です。 

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
      // PHP program to demonstrate Range Update    // and Point Queries Without using BIT    // Updates such that getElement() gets an    // increased value when queried from l to r.    function   update  (  &  $arr     $l     $r     $val  )   {   $arr  [  $l  ]   +=   $val  ;   if  (  $r   +   1    <   sizeof  (  $arr  ))   $arr  [  $r   +   1  ]   -=   $val  ;   }   // Get the element indexed at i    function   getElement  (  &  $arr     $i  )   {   // To get ith element sum of all the elements    // from 0 to i need to be computed    $res   =   0  ;   for   (  $j   =   0   ;   $j    <=   $i  ;   $j  ++  )   $res   +=   $arr  [  $j  ];   return   $res  ;   }   // Driver Code   $arr   =   array  (  0     0     0     0     0  );   $n   =   sizeof  (  $arr  );   $l   =   2  ;   $r   =   4  ;   $val   =   2  ;   update  (  $arr     $l     $r     $val  );   // Find the element at Index 4    $index   =   4  ;   echo  (  'Element at index '   .   $index   .   ' is '   .   getElement  (  $arr     $index  )   .   '  n  '  );   $l   =   0  ;   $r   =   3  ;   $val   =   4  ;   update  (  $arr     $l     $r     $val  );   // Find the element at Index 3    $index   =   3  ;   echo  (  'Element at index '   .   $index   .   ' is '   .   getElement  (  $arr     $index  ));   // This code is contributed by Code_Mech   ?>   
JavaScript
   //JavaScript program to demonstrate Range Update   // and Point Queries Without using BIT   // Updates such that getElement() gets an increased   // value when queried from l to r.   function     update  (  arr       l       r       val  )   {      arr  [  l  ]     +=     val  ;      arr  [  r  +  1  ]     -=     val  ;   }   // Get the element indexed at i   function     getElement  (  rr       i  )   {      // To get ith element sum of all the elements      // from 0 to i need to be computed      let     res     =     0  ;      for     (  let     j     =     0     ;     j      <=     i  ;     j  ++  )      res     +=     arr  [  j  ];      return     res  ;   }   // Driver program to test above function      let     arr     =     [  0       0       0       0       0  ];      let     n     =     arr  .  length  ;      let     l     =     2       r     =     4       val     =     2  ;      update  (  arr       l       r       val  );      // Find the element at Index 4      let     index     =     4  ;      console  .  log  (  '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  .  log  (  'Element at index '    index    ' is '    getElement  (  arr       index  ));   // This code is contributed by vikkycirus   

出力:

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  ;     i   <  n  ;     i  ++  )      updateBIT  (  BITree       n       i       arr  [  i  ]);      // Uncomment below lines to see contents of BITree[]      //for (int i=1; i <=n; i++)      // cout  < < BITree[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[]   int     getSum  (  int     BITree  []     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     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 [24]      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 [03]      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 [24]      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 [03]      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   # 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   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 [24]   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 [03]   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 [24]       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 [03]       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   
JavaScript
   // 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.   function     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.   function     constructBITree  (  arr       n  )     {      // Create and initialize BITree[] as 0      let     BITree     =     new     Array  (  n  +  1  ).  fill  (  0  );      // Store the actual values in BITree[] using update()      for     (  let     i     =     0  ;     i      <     n  ;     i  ++  )     {      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[]   function     getSum  (  BITree       index  )     {      let     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     sum  ;   }   // Updates such that getElement() gets an increased   // value when queried from l to r.   function     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  );   }   // Test the functions   let     arr     =     [  0       0       0       0       0  ];   let     n     =     arr  .  length  ;   let     BITree     =     constructBITree  (  arr       n  );   // Add 2 to all the element from [24]   let     l     =     2       r     =     4       val     =     2  ;   update  (  BITree       l       r       n       val  );   // Find the element at Index 4   let     index     =     4  ;   console  .  log  (  `Element at index   ${  index  }   is   ${  getSum  (  BITree    index  )  }  `  );   // Add 2 to all the element from [03]   l     =     0       r     =     3       val     =     4  ;   update  (  BITree       l       r       n       val  );   // Find the element at Index 3   index     =     3  ;   console  .  log  (  `Element at index   ${  index  }   is   ${  getSum  (  BITree    index  )  }  `  );   

出力:

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

時間計算量 : O(q * log n) + O(n * log n) ここで、q はクエリの数です。 

補助スペース: の上)

ほとんどのクエリが getElement() の場合はメソッド 1 が効率的で、ほとんどのクエリが update() の場合はメソッド 2 が効率的で、両方のクエリが混在する場合はメソッド 3 が推奨されます。