Largest Sum Subarray Range Queries

Last Updated : 8 Jul, 2026

Given an array arr[]  and a list of queries queries[][]. Each query can be one of the following two types:

  • Update Query: [1, index, value] --> Update the element at position index in the array to the given value.
  • Range Query: [2, L, R] --> Compute and return the maximum sum of any subarray within the  subarray from index L to R (inclusive).

Process all queries sequentially and return a list containing the results of all Type 2 queries.

Note: All operations follow 0-based indexing.

Examples: 

Input: arr[] = [-2, -3, 4, -1, -2, 1, 5, -3], queries[][] = [[2, 4, 7], [1, 0, 10], [2, 0, 2]]
Output: [6, 11]
Explanation:
For the first query [2, 4, 7]:
The range is [-2, 1, 5, -3].
The maximum subarray sum is 6, obtained from subarray [1, 5].
For the second query [1, 0, 10]:
The updated array becomes: [10, -3, 4, -1, -2, 1, 5, -3]
For the third query [2, 0, 2]:
The range is [10, -3, 4].
The maximum subarray sum is 11, obtained from subarray [10, -3, 4].

Input: arr[] = [-5, -2, -8, 3, -1], queries[][] = [[2, 0, 2], [2, 3, 4]]
Output: [-2, 3]
Explanation:
For the first query [2, 0, 2]:
The range is [-5, -2, -8].
The maximum subarray sum is -2, obtained from subarray [-2].
For the second query [2, 3, 4]:
The range is [3, -1].
The maximum subarray sum is 3, obtained from subarray [3].

Try It Yourself
redirect icon

[Naive Approach] Process Every Range Query Using Kadane's Algorithm - O(q × n) Time and O(1) Space

Process the queries one by one. For an update query [1, index, value], update the corresponding array element. For a range query [2, L, R], run Kadane's Algorithm on the subarray arr[L...R] to find its maximum subarray sum and store the result. Since each range query may scan up to n elements, the overall time complexity is O(q × n), while the auxiliary space complexity is O(1).

C++
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

vector<int> largestSumQueries(vector<int> &arr, vector<vector<int>> &queries)
{

    vector<int> res;

    for (auto &q : queries)
    {

        // Update Query
        if (q[0] == 1)
        {
            arr[q[1]] = q[2];
        }

        // Range Query
        else
        {

            int L = q[1];
            int R = q[2];

            int curr = arr[L];
            int best = arr[L];

            for (int i = L + 1; i <= R; i++)
            {
                curr = max(arr[i], curr + arr[i]);
                best = max(best, curr);
            }

            res.push_back(best);
        }
    }

    return res;
}

int main()
{

    vector<int> arr = {-5, -2, -8, 3, -1};

    vector<vector<int>> queries = {{2, 0, 2}, {2, 3, 4}};

    vector<int> ans = largestSumQueries(arr, queries);

    cout << "[";

    for (int i = 0; i < ans.size(); i++)
    {
        cout << ans[i];
        if (i != ans.size() - 1)
            cout << ", ";
    }

    cout << "]";

    return 0;
}
Java
import java.util.ArrayList;

public class GFG {

    public static int[] largestSumQueries(int[] arr, int[][] queries)
    {

        ArrayList<Integer> res = new ArrayList<>();

        for (int[] q : queries) {

            // Update Query
            if (q[0] == 1) {
                arr[q[1]] = q[2];
            }

            // Range Query
            else {

                int L = q[1];
                int R = q[2];

                int curr = arr[L];
                int best = arr[L];

                for (int i = L + 1; i <= R; i++) {
                    curr = Math.max(arr[i], curr + arr[i]);
                    best = Math.max(best, curr);
                }

                res.add(best);
            }
        }

        int[] ans = new int[res.size()];
        for (int i = 0; i < res.size(); i++)
            ans[i] = res.get(i);

        return ans;
    }

    public static void main(String[] args)
    {

        int[] arr = { -5, -2, -8, 3, -1 };

        int[][] queries = { { 2, 0, 2 }, { 2, 3, 4 } };

        int[] ans = largestSumQueries(arr, queries);

        System.out.print("[");

        for (int i = 0; i < ans.length; i++) {
            System.out.print(ans[i]);
            if (i != ans.length - 1)
                System.out.print(", ");
        }

        System.out.print("]");
    }
}
Python
def largestSumQueries(arr, queries):
    res = []

    for q in queries:
        # Update Query
        if q[0] == 1:
            arr[q[1]] = q[2]
        # Range Query
        else:
            L = q[1]
            R = q[2]

            curr = arr[L]
            best = arr[L]

            for i in range(L + 1, R + 1):
                curr = max(arr[i], curr + arr[i])
                best = max(best, curr)

            res.append(best)
    return res


if __name__ == '__main__':
    arr = [-5, -2, -8, 3, -1]
    queries = [[2, 0, 2], [2, 3, 4]]
    ans = largestSumQueries(arr, queries)
    print('[', end='')
    for i in range(len(ans)):
        print(ans[i], end='' if i == len(ans) - 1 else ', ')
    print(']')
C#
using System;
using System.Collections.Generic;

public class GFG {
    public static List<int>
    largestSumQueries(int[] arr, int[][] queries)
    {
        List<int> res = new List<int>();

        foreach(int[] q in queries)
        {
            // Update Query
            if (q[0] == 1) {
                arr[q[1]] = q[2];
            }

            // Range Query
            else {
                int L = q[1];
                int R = q[2];

                int curr = arr[L];
                int best = arr[L];

                for (int i = L + 1; i <= R; i++) {
                    curr = Math.Max(arr[i], curr + arr[i]);
                    best = Math.Max(best, curr);
                }

                res.Add(best);
            }
        }

        return res;
    }

    public static void Main()
    {
        int[] arr = { -5, -2, -8, 3, -1 };

        int[][] queries = { new int[] { 2, 0, 2 },
                            new int[] { 2, 3, 4 } };

        List<int> ans = largestSumQueries(arr, queries);

        Console.Write("[");

        for (int i = 0; i < ans.Count; i++) {
            Console.Write(ans[i]);
            if (i != ans.Count - 1)
                Console.Write(", ");
        }

        Console.Write("]");
    }
}
JavaScript
function largestSumQueries(arr, queries)
{
    let res = [];

    for (let q of queries) {
        // Update Query
        if (q[0] === 1) {
            arr[q[1]] = q[2];
        }
        // Range Query
        else {
            let L = q[1];
            let R = q[2];

            let curr = arr[L];
            let best = arr[L];

            for (let i = L + 1; i <= R; i++) {
                curr = Math.max(arr[i], curr + arr[i]);
                best = Math.max(best, curr);
            }

            res.push(best);
        }
    }
    return res;
}

// Driver Code
let arr = [ -5, -2, -8, 3, -1 ];
let queries = [ [ 2, 0, 2 ], [ 2, 3, 4 ] ];
let ans = largestSumQueries(arr, queries);
console.log("[" + ans.join(", ") + "]");

Output
[-2, 3]

[Expected Approach] Segment Tree with Maximum Subarray Sum - O((n + q) × log n) Time and O(n) Space

The idea is to use a Segment Tree where each node stores four values for its segment: sum, maximum prefix sum, maximum suffix sum, and maximum subarray sum. These values allow two child segments to be merged efficiently. For an update query, only the nodes on the path from the updated index to the root are recomputed. For a range query, the required segments are merged, and the resulting node's maxsum gives the maximum subarray sum in the queried range.

Working of Approach:

  • Build a Segment Tree where each node stores the segment's sum, maximum prefix sum, maximum suffix sum, and maximum subarray sum.
  • For an Update Query, update the corresponding leaf node and recompute only the affected ancestor nodes.
  • For a Range Query, retrieve the required segments from the tree and merge them to obtain the answer.
  • The maxsum of the merged node gives the maximum subarray sum for the queried range.
  • Repeat this process for all queries and return the results of every range query.

Let us understand with an example:
Input: arr[] = [-5, -2, -8, 3, -1], queries[][] = [[2, 0, 2], [2, 3, 4]]

  • Build a Segment Tree where each node stores the segment's sum, maximum prefix sum, maximum suffix sum, and maximum subarray sum.
  • Process the first query [2, 0, 2] by querying the segment tree for the range [-5, -2, -8]. After merging the required nodes, the returned maxsum is -2, which is added to the answer.
  • Process the second query [2, 3, 4] by querying the range [3, -1]. Merging the corresponding nodes gives maxsum = 3, which is added to the answer.
  • Since there are no update queries, the segment tree remains unchanged throughout the execution.
  • Finally, return the collected answers [-2, 3].
C++
#include <iostream>
#include <vector>
#include <algorithm>
#include <climits>
using namespace std;

class node
{
  public:
    int sum, prefixsum, suffixsum, maxsum;
};

vector<node> tree;
int n;

node merge(node left, node right)
{
    node res;
    res.sum = left.sum + right.sum;
    res.prefixsum = max(left.prefixsum, left.sum + right.prefixsum);
    res.suffixsum = max(right.suffixsum, right.sum + left.suffixsum);
    res.maxsum =
        max({res.prefixsum, res.suffixsum, left.maxsum, right.maxsum, left.suffixsum + right.prefixsum});
    return res;
}

void build(vector<int> &arr, int low, int high, int index)
{
    if (low == high)
    {
        tree[index] = {arr[low], arr[low], arr[low], arr[low]};
        return;
    }
    int mid = (low + high) / 2;
    build(arr, low, mid, 2 * index + 1);
    build(arr, mid + 1, high, 2 * index + 2);
    tree[index] = merge(tree[2 * index + 1], tree[2 * index + 2]);
}

void updateUtil(int index, int low, int high, int idx, int value)
{
    if (low == high)
    {
        tree[index] = {value, value, value, value};
        return;
    }
    int mid = (low + high) / 2;
    if (idx <= mid)
        updateUtil(2 * index + 1, low, mid, idx, value);
    else
        updateUtil(2 * index + 2, mid + 1, high, idx, value);
    tree[index] = merge(tree[2 * index + 1], tree[2 * index + 2]);
}

node queryUtil(int index, int low, int high, int l, int r)
{
    if (r < low || high < l)
        return {INT_MIN, INT_MIN, INT_MIN, INT_MIN};
    if (l <= low && high <= r)
        return tree[index];
    int mid = (low + high) / 2;
    if (l > mid)
        return queryUtil(2 * index + 2, mid + 1, high, l, r);
    if (r <= mid)
        return queryUtil(2 * index + 1, low, mid, l, r);
    node left = queryUtil(2 * index + 1, low, mid, l, r);
    node right = queryUtil(2 * index + 2, mid + 1, high, l, r);
    return merge(left, right);
}

vector<int> largestSumQueries(vector<int> &arr, vector<vector<int>> &queries)
{

    n = arr.size();

    // Build the segment tree
    tree.resize(4 * n);
    build(arr, 0, n - 1, 0);

    vector<int> result;
    for (auto &q : queries)
    {

        // update at index ind with value x
        if (q[0] == 1)
        {
            int ind = q[1];
            int x = q[2];
            updateUtil(0, 0, n - 1, ind, x);
        }

        // maximum sum from l to r
        else if (q[0] == 2)
        {
            int l = q[1];
            int r = q[2];
            result.push_back(queryUtil(0, 0, n - 1, l, r).maxsum);
        }
    }
    return result;
}

int main()
{

    vector<int> arr = {-5, -2, -8, 3, -1};

    vector<vector<int>> queries = {{2, 0, 2}, {2, 3, 4}};

    vector<int> ans = largestSumQueries(arr, queries);

    cout << "[";

    for (int i = 0; i < ans.size(); i++)
    {
        cout << ans[i];
        if (i != ans.size() - 1)
            cout << ", ";
    }

    cout << "]";

    return 0;
}
Java
import java.util.Arrays;

class node {
    public int sum, prefixsum, suffixsum, maxsum;
}

public class GFG {

    static node[] tree;
    static int n;

    static node merge(node left, node right)
    {
        node res = new node();
        res.sum = left.sum + right.sum;
        res.prefixsum = Math.max(
            left.prefixsum, left.sum + right.prefixsum);
        res.suffixsum = Math.max(
            right.suffixsum, right.sum + left.suffixsum);
        res.maxsum = Math.max(
            Math.max(res.prefixsum, res.suffixsum),
            Math.max(left.maxsum,
                     Math.max(right.maxsum,
                              left.suffixsum
                                  + right.prefixsum)));
        return res;
    }

    static void build(int[] arr, int low, int high,
                      int index)
    {
        if (low == high) {
            tree[index] = new node();
            tree[index].sum = arr[low];
            tree[index].prefixsum = arr[low];
            tree[index].suffixsum = arr[low];
            tree[index].maxsum = arr[low];
            return;
        }

        int mid = (low + high) / 2;

        build(arr, low, mid, 2 * index + 1);
        build(arr, mid + 1, high, 2 * index + 2);

        tree[index] = merge(tree[2 * index + 1],
                            tree[2 * index + 2]);
    }

    static void updateUtil(int index, int low, int high,
                           int idx, int value)
    {

        if (low == high) {
            tree[index] = new node();
            tree[index].sum = value;
            tree[index].prefixsum = value;
            tree[index].suffixsum = value;
            tree[index].maxsum = value;
            return;
        }

        int mid = (low + high) / 2;

        if (idx <= mid)
            updateUtil(2 * index + 1, low, mid, idx, value);
        else
            updateUtil(2 * index + 2, mid + 1, high, idx,
                       value);

        tree[index] = merge(tree[2 * index + 1],
                            tree[2 * index + 2]);
    }

    static node queryUtil(int index, int low, int high,
                          int l, int r)
    {

        if (r < low || high < l)
            return new node() {
                {
                    sum = Integer.MIN_VALUE;
                    prefixsum = Integer.MIN_VALUE;
                    suffixsum = Integer.MIN_VALUE;
                    maxsum = Integer.MIN_VALUE;
                }
            };

        if (l <= low && high <= r)
            return tree[index];

        int mid = (low + high) / 2;

        if (l > mid)
            return queryUtil(2 * index + 2, mid + 1, high,
                             l, r);

        if (r <= mid)
            return queryUtil(2 * index + 1, low, mid, l, r);

        node left
            = queryUtil(2 * index + 1, low, mid, l, r);

        node right
            = queryUtil(2 * index + 2, mid + 1, high, l, r);

        return merge(left, right);
    }

    static int[] largestSumQueries(int[] arr,
                                   int[][] queries)
    {

        n = arr.length;

        // Build the segment tree
        tree = new node[4 * n];
        build(arr, 0, n - 1, 0);

        int[] result = new int[queries.length];
        int resultIndex = 0;

        for (int[] q : queries) {

            // update at index ind with value x
            if (q[0] == 1) {

                int ind = q[1];
                int x = q[2];

                updateUtil(0, 0, n - 1, ind, x);
            }

            // maximum sum from l to r
            else if (q[0] == 2) {

                int l = q[1];
                int r = q[2];

                result[resultIndex++]
                    = queryUtil(0, 0, n - 1, l, r).maxsum;
            }
        }

        return Arrays.copyOf(result, resultIndex);
    }

    public static void main(String[] args)
    {

        int[] arr = { -5, -2, -8, 3, -1 };

        int[][] queries = { { 2, 0, 2 }, { 2, 3, 4 } };

        int[] ans = largestSumQueries(arr, queries);

        System.out.print("[");

        for (int i = 0; i < ans.length; i++) {
            System.out.print(ans[i]);
            if (i != ans.length - 1)
                System.out.print(", ");
        }

        System.out.print("]");
    }
}
Python
class Node:

    def __init__(self):
        self.sum = 0
        self.prefixsum = 0
        self.suffixsum = 0
        self.maxsum = 0


tree = []
n = 0


def merge(left, right):
    res = Node()
    res.sum = left.sum + right.sum
    res.prefixsum = max(left.prefixsum, left.sum + right.prefixsum)
    res.suffixsum = max(right.suffixsum, right.sum + left.suffixsum)
    res.maxsum = max(
        max(res.prefixsum, res.suffixsum),
        max(left.maxsum,
            max(right.maxsum, left.suffixsum + right.prefixsum)))
    return res


def build(arr, low, high, index):
    if low == high:
        tree[index] = Node()
        tree[index].sum = arr[low]
        tree[index].prefixsum = arr[low]
        tree[index].suffixsum = arr[low]
        tree[index].maxsum = arr[low]
        return

    mid = (low + high) // 2

    build(arr, low, mid, 2 * index + 1)
    build(arr, mid + 1, high, 2 * index + 2)

    tree[index] = merge(tree[2 * index + 1],
                        tree[2 * index + 2])


def updateUtil(index, low, high, idx, value):
    if low == high:
        tree[index] = Node()
        tree[index].sum = value
        tree[index].prefixsum = value
        tree[index].suffixsum = value
        tree[index].maxsum = value
        return

    mid = (low + high) // 2

    if idx <= mid:
        updateUtil(2 * index + 1, low, mid, idx, value)
    else:
        updateUtil(2 * index + 2, mid + 1, high, idx, value)

    tree[index] = merge(tree[2 * index + 1],
                        tree[2 * index + 2])


def queryUtil(index, low, high, l, r):
    if r < low or high < l:
        temp = Node()
        temp.sum = float("-inf")
        temp.prefixsum = float("-inf")
        temp.suffixsum = float("-inf")
        temp.maxsum = float("-inf")
        return temp

    if l <= low and high <= r:
        return tree[index]

    mid = (low + high) // 2

    if l > mid:
        return queryUtil(2 * index + 2, mid + 1, high, l, r)

    if r <= mid:
        return queryUtil(2 * index + 1, low, mid, l, r)

    left = queryUtil(2 * index + 1, low, mid, l, r)
    right = queryUtil(2 * index + 2, mid + 1, high, l, r)

    return merge(left, right)


def largestSumQueries(arr, queries):
    global tree, n

    n = len(arr)

    # Build the segment tree
    tree = [None] * (4 * n)
    build(arr, 0, n - 1, 0)

    result = []

    for q in queries:

        # update at index ind with value x
        if q[0] == 1:
            ind = q[1]
            x = q[2]
            updateUtil(0, 0, n - 1, ind, x)

        # maximum sum from l to r
        elif q[0] == 2:
            l = q[1]
            r = q[2]
            result.append(queryUtil(0, 0, n - 1, l, r).maxsum)

    return result


if __name__ == "__main__":

    arr = [-5, -2, -8, 3, -1]

    queries = [
        [2, 0, 2],
        [2, 3, 4]
    ]

    ans = largestSumQueries(arr, queries)

    print(ans)
C#
using System;

public class node {
    public int sum, prefixsum, suffixsum, maxsum;
}

public class GFG {
    static node[] tree;
    static int n;

    static node merge(node left, node right)
    {
        node res = new node();
        res.sum = left.sum + right.sum;
        res.prefixsum = Math.Max(
            left.prefixsum, left.sum + right.prefixsum);
        res.suffixsum = Math.Max(
            right.suffixsum, right.sum + left.suffixsum);
        res.maxsum = Math.Max(
            Math.Max(res.prefixsum, res.suffixsum),
            Math.Max(left.maxsum,
                     Math.Max(right.maxsum,
                              left.suffixsum
                                  + right.prefixsum)));
        return res;
    }

    static void build(int[] arr, int low, int high,
                      int index)
    {
        if (low == high) {
            tree[index] = new node();
            tree[index].sum = arr[low];
            tree[index].prefixsum = arr[low];
            tree[index].suffixsum = arr[low];
            tree[index].maxsum = arr[low];
            return;
        }

        int mid = (low + high) / 2;

        build(arr, low, mid, 2 * index + 1);
        build(arr, mid + 1, high, 2 * index + 2);

        tree[index] = merge(tree[2 * index + 1],
                            tree[2 * index + 2]);
    }

    static void updateUtil(int index, int low, int high,
                           int idx, int value)
    {
        if (low == high) {
            tree[index] = new node();
            tree[index].sum = value;
            tree[index].prefixsum = value;
            tree[index].suffixsum = value;
            tree[index].maxsum = value;
            return;
        }

        int mid = (low + high) / 2;

        if (idx <= mid)
            updateUtil(2 * index + 1, low, mid, idx, value);
        else
            updateUtil(2 * index + 2, mid + 1, high, idx,
                       value);

        tree[index] = merge(tree[2 * index + 1],
                            tree[2 * index + 2]);
    }

    static node queryUtil(int index, int low, int high,
                          int l, int r)
    {
        if (r < low || high < l) {
            return new node{ sum = int.MinValue,
                             prefixsum = int.MinValue,
                             suffixsum = int.MinValue,
                             maxsum = int.MinValue };
        }

        if (l <= low && high <= r)
            return tree[index];

        int mid = (low + high) / 2;

        if (l > mid)
            return queryUtil(2 * index + 2, mid + 1, high,
                             l, r);

        if (r <= mid)
            return queryUtil(2 * index + 1, low, mid, l, r);

        node left
            = queryUtil(2 * index + 1, low, mid, l, r);

        node right
            = queryUtil(2 * index + 2, mid + 1, high, l, r);

        return merge(left, right);
    }

    static int[] largestSumQueries(int[] arr, int[][] queries)
    {
        n = arr.Length;

        // Build the segment tree
        tree = new node[4 * n];
        build(arr, 0, n - 1, 0);

        int[] result = new int[queries.Length];
        int resultIndex = 0;

        foreach(int[] q in queries)
        {
            // update at index ind with value x
            if (q[0] == 1) {
                int ind = q[1];
                int x = q[2];
                updateUtil(0, 0, n - 1, ind, x);
            }

            // maximum sum from l to r
            else if (q[0] == 2) {
                int l = q[1];
                int r = q[2];
                result[resultIndex++]
                    = queryUtil(0, 0, n - 1, l, r).maxsum;
            }
        }

        int[] finalResult = new int[resultIndex];
        Array.Copy(result, 0, finalResult, 0, resultIndex);

        return finalResult;
    }

    public static void Main()
    {
        int[] arr = { -5, -2, -8, 3, -1 };

        int[][] queries = { new int[] { 2, 0, 2 },
                            new int[] { 2, 3, 4 } };

        int[] ans = largestSumQueries(arr, queries);

        Console.Write("[");

        for (int i = 0; i < ans.Length; i++) {
            Console.Write(ans[i]);
            if (i != ans.Length - 1)
                Console.Write(", ");
        }

        Console.Write("]");
    }
}
JavaScript
class node {
    constructor()
    {
        this.sum = 0;
        this.prefixsum = 0;
        this.suffixsum = 0;
        this.maxsum = 0;
    }
}

let tree = [];
let n = 0;

function merge(left, right)
{
    let res = new node();
    res.sum = left.sum + right.sum;
    res.prefixsum = Math.max(left.prefixsum,
                             left.sum + right.prefixsum);
    res.suffixsum = Math.max(right.suffixsum,
                             right.sum + left.suffixsum);
    res.maxsum = Math.max(
        Math.max(res.prefixsum, res.suffixsum),
        Math.max(
            left.maxsum,
            Math.max(right.maxsum,
                     left.suffixsum + right.prefixsum)));
    return res;
}

function build(arr, low, high, index)
{
    if (low === high) {
        tree[index] = new node();
        tree[index].sum = arr[low];
        tree[index].prefixsum = arr[low];
        tree[index].suffixsum = arr[low];
        tree[index].maxsum = arr[low];
        return;
    }

    let mid = Math.floor((low + high) / 2);

    build(arr, low, mid, 2 * index + 1);
    build(arr, mid + 1, high, 2 * index + 2);

    tree[index]
        = merge(tree[2 * index + 1], tree[2 * index + 2]);
}

function updateUtil(index, low, high, idx, value)
{
    if (low === high) {
        tree[index] = new node();
        tree[index].sum = value;
        tree[index].prefixsum = value;
        tree[index].suffixsum = value;
        tree[index].maxsum = value;
        return;
    }

    let mid = Math.floor((low + high) / 2);

    if (idx <= mid)
        updateUtil(2 * index + 1, low, mid, idx, value);
    else
        updateUtil(2 * index + 2, mid + 1, high, idx,
                   value);

    tree[index]
        = merge(tree[2 * index + 1], tree[2 * index + 2]);
}

function queryUtil(index, low, high, l, r)
{

    if (l <= low && high <= r)
        return tree[index];

    let mid = Math.floor((low + high) / 2);

    if (l > mid)
        return queryUtil(2 * index + 2, mid + 1, high, l,
                         r);

    if (r <= mid)
        return queryUtil(2 * index + 1, low, mid, l, r);

    let left = queryUtil(2 * index + 1, low, mid, l, r);
    let right
        = queryUtil(2 * index + 2, mid + 1, high, l, r);

    return merge(left, right);
}

function largestSumQueries(arr, queries)
{

    n = arr.length;

    // Build the segment tree
    tree = new Array(4 * n);
    build(arr, 0, n - 1, 0);

    let result = [];

    for (let q of queries) {

        // update at index ind with value x
        if (q[0] === 1) {
            let ind = q[1];
            let x = q[2];
            updateUtil(0, 0, n - 1, ind, x);
        }

        // maximum sum from l to r
        else if (q[0] === 2) {
            let l = q[1];
            let r = q[2];
            result.push(
                queryUtil(0, 0, n - 1, l, r).maxsum);
        }
    }

    return result;
}

// Driver code
let arr = [ -5, -2, -8, 3, -1 ];
let queries = [ [ 2, 0, 2 ], [ 2, 3, 4 ] ];
let ans = largestSumQueries(arr, queries);
console.log("[" + ans.join(", ") + "]");

Output
[-2, 3]
Comment