Skip to content
Related Articles

Related Articles

Improve Article
Maximum Sum Increasing Subsequence using Binary Indexed Tree
  • Difficulty Level : Hard
  • Last Updated : 05 Nov, 2020

Given an array of size n. Find the maximum sum of an increasing subsequence.
Examples: 

Input :  arr[] = { 1, 20, 4, 2, 5 }
Output : Maximum sum of increasing subsequence is = 21
The subsequence  1, 20 gives maximum sum which is 21

Input  : arr[] = { 4, 2, 3, 1, 5, 8 }
Output : Maximum sum of increasing subsequence is = 18
The subsequence  2, 3, 5, 8 gives maximum sum which is 18

Prerequisite 
The solution makes the use of Binary Indexed Tree and map. 
Dynamic Programming Approach: DP approach which is in O(n^2) . 
Solution 
Step 1 : 
The first step is to insert all values in a map, later we can map these array values to the indexes of Binary Indexed Tree.
Step 2 : 
Iterate the map and assign indexes. What this would do is for an array { 4, 2, 3, 8, 5, 2 } 
2 will be assigned index 1 
3 will be assigned index 2 
4 will be assigned index 3 
5 will be assigned index 4 
8 will be assigned index 5
Step 3 : 
Construct the Binary Indexed Tree.
Step 4 : 
For every value in the given array do the following. 
Find the maximum sum till that position using BIT and then update the BIT with New Maximum Value
Step 5 : 
Returns the maximum sum which is present at last position in Binary Indexed Tree. 
 

C++




// C++ code for Maximum Sum
// Increasing Subsequence
#include <bits/stdc++.h>
using namespace std;
 
// Returns the maximum value of
// the increasing subsequence
// till that index
// Link to understand getSum function
int getSum(int BITree[], int index)
{
    int sum = 0;
    while (index > 0) {
        sum = max(sum, BITree[index]);
        index -= index & (-index);
    }
    return sum;
}
 
// Updates a node in Binary Index
// Tree (BITree) at given index in
// BITree. The max value is updated
// by taking max  of 'val' and the
// already present value in the node.
void updateBIT(int BITree[], int newIndex,
               int index, int val)
{
    while (index <= newIndex) {
        BITree[index] = max(val, BITree[index]);
        index += index & (-index);
    }
}
 
// maxSumIS() returns the maximum
// sum of increasing subsequence
// in arr[] of size n
int maxSumIS(int arr[], int n)
{
    int newindex = 0, max_sum;
 
    map<int, int> uniqueArr;
 
    // Inserting all values in map uniqueArr
    for (int i = 0; i < n; i++) {
        uniqueArr[arr[i]] = 0;
    }
 
    // Assigning indexes to all
    // the  values present in map
    for (map<int, int>::iterator it = uniqueArr.begin();
         it != uniqueArr.end(); it++) {
 
        // newIndex is actually the count of
        // unique values in the array.
        newindex++;
 
        uniqueArr[it->first] = newindex;
    }
 
    // Constructing the BIT
    int* BITree = new int[newindex + 1];
 
    // Initializing the BIT
    for (int i = 0; i <= newindex; i++) {
        BITree[i] = 0;
    }
 
    for (int i = 0; i < n; i++) {
        // Finding maximum sum till this element
        max_sum = getSum(BITree, uniqueArr[arr[i]] - 1);
 
        // Updating the BIT  with new maximum sum
        updateBIT(BITree, newindex,
                 uniqueArr[arr[i]], max_sum + arr[i]);
    }
 
    // return maximum sum
    return getSum(BITree, newindex);
}
 
// Driver program
int main()
{
    int arr[] = { 1, 101, 2, 3, 100, 4, 5 };
    int n = sizeof(arr) / sizeof(arr[0]);
    cout << "Maximum sum is = " << maxSumIS(arr, n);
 
    return 0;
}

Java




// JAVA code for Maximum Sum
// Increasing Subsequence
import java.util.*;
class GFG{
 
// Returns the maximum value of
// the increasing subsequence
// till that index
// Link to understand getSum function
// binary-indexed-tree-or-fenwick-tree-2/
static int getSum(int BITree[], int index)
{
  int sum = 0;
  while (index > 0)
  {
    sum = Math.max(sum,
                   BITree[index]);
    index -= index & (-index);
  }
  return sum;
}
 
// Updates a node in Binary Index
// Tree (BITree) at given index in
// BITree. The max value is updated
// by taking max  of 'val' and the
// already present value in the node.
static void updateBIT(int BITree[],
                      int newIndex,
                      int index, int val)
{
  while (index <= newIndex)
  {
    BITree[index] = Math.max(val,
                             BITree[index]);
    index += index & (-index);
  }
}
 
// maxSumIS() returns the maximum
// sum of increasing subsequence
// in arr[] of size n
static int maxSumIS(int arr[],
                    int n)
{
  int newindex = 0, max_sum;
 
  HashMap<Integer,
          Integer> uniqueArr =
          new HashMap<>();
 
  // Inserting all values in map
  // uniqueArr
  for (int i = 0; i < n; i++)
  {
    uniqueArr.put(arr[i], 0);
  }
 
  // Assigning indexes to all
  // the  values present in map
  for (Map.Entry<Integer,
                 Integer> entry :
                 uniqueArr.entrySet())
  {
    // newIndex is actually the
    // count of unique values in
    // the array.
    newindex++;
 
    uniqueArr.put(entry.getKey(),
                  newindex);
  }
 
  // Constructing the BIT
  int []BITree = new int[newindex + 1];
 
  // Initializing the BIT
  for (int i = 0; i <= newindex; i++)
  {
    BITree[i] = 0;
  }
 
  for (int i = 0; i < n; i++)
  {
    // Finding maximum sum till
    // this element
    max_sum = getSum(BITree,
                     uniqueArr.get(arr[i]) - 3);
 
    // Updating the BIT with
    // new maximum sum
    updateBIT(BITree, newindex,
              uniqueArr.get(arr[i]),
              max_sum + arr[i]);
  }
 
  // return maximum sum
  return getSum(BITree,
                newindex);
}
 
// Driver program
public static void main(String[] args)
{
  int arr[] = {1, 101, 2,
               3, 100, 4, 5};
  int n = arr.length;
  System.out.print("Maximum sum is = "
                    maxSumIS(arr, n));
}
}
 
// This code is contributed by shikhasingrajput

C#




// C# code for Maximum Sum
// Increasing Subsequence
using System;
using System.Collections.Generic;
class GFG{
 
// Returns the maximum value of
// the increasing subsequence
// till that index
// Link to understand getSum function
// binary-indexed-tree-or-fenwick-tree-2/
static int getSum(int []BITree,
                  int index)
{
  int sum = 0;
  while (index > 0)
  {
    sum = Math.Max(sum,
                   BITree[index]);
    index -= index & (-index);
  }
  return sum;
}
 
// Updates a node in Binary Index
// Tree (BITree) at given index in
// BITree. The max value is updated
// by taking max  of 'val' and the
// already present value in the node.
static void updateBIT(int []BITree,
                      int newIndex,
                      int index, int val)
{
  while (index <= newIndex)
  {
    BITree[index] = Math.Max(val,
                             BITree[index]);
    index += index & (-index);
  }
}
 
// maxSumIS() returns the maximum
// sum of increasing subsequence
// in []arr of size n
static int maxSumIS(int []arr,
                    int n)
{
  int newindex = 0, max_sum;
 
  Dictionary<int,
             int> uniqueArr =
             new Dictionary<int,
                            int>();
 
  // Inserting all values in map
  // uniqueArr
  for (int i = 0; i < n; i++)
  {
    uniqueArr.Add(arr[i], 0);
  }
    Dictionary<int,
               int> uniqueArr1 =
               new Dictionary<int,
                              int>();
 
  // Assigning indexes to all
  // the  values present in map
  foreach (KeyValuePair<int,
                        int> entry in
                        uniqueArr)
  {
    // newIndex is actually the
    // count of unique values in
    // the array.
    newindex++;
    if(uniqueArr1.ContainsKey(entry.Key))
      uniqueArr1[entry.Key] = newindex;
    else
      uniqueArr1.Add(entry.Key,
                     newindex);
  }
 
  // Constructing the BIT
  int []BITree = new int[newindex + 1];
 
  // Initializing the BIT
  for (int i = 0; i <= newindex; i++)
  {
    BITree[i] = 0;
  }
 
  for (int i = 0; i < n; i++)
  {
    // Finding maximum sum till
    // this element
    max_sum = getSum(BITree,
                     uniqueArr1[arr[i]] - 4);
 
    // Updating the BIT with
    // new maximum sum
    updateBIT(BITree, newindex,
              uniqueArr1[arr[i]],
              max_sum + arr[i]);
  }
 
  // return maximum sum
  return getSum(BITree,
                newindex);
}
 
// Driver program
public static void Main(String[] args)
{
  int []arr = {1, 101, 2,
               3, 100, 4, 5};
  int n = arr.Length;
  Console.Write("Maximum sum is = "
                 maxSumIS(arr, n));
}
}
 
// This code is contributed by shikhasingrajput
Output
Maximum sum is = 106





Note 
Time Complexity of the solution 
O(nLogn) for the map and O(nLogn) for updating and getting sum. So overall complexity is still O(nLogn).

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with industry experts, please refer Geeks Classes Live




My Personal Notes arrow_drop_up
Recommended Articles
Page :