arraysalgorithmsortinggreedysegment-tree

Maximum Sum Elements in Range


Given an array 'A' of size 'N' containing integers. You need to answer 'Q' queries of type [ L R X Y ]. In each of the query you need to select at least 'X' elements and at most 'Y' elements from range 'L' to 'R' of the array 'A' such that their sum is maximum.

Output the maximum sum achievable for each of the query.

Example :

N = 5 
A = [ 1, 2, -1, -2, 3 ]
Q = [ [ 1, 3, 1, 2 ] , [ 3, 4, 1, 2 ] ]

Output : 3, -1

Expanation :

For query 1, we select integers 1 and 2 to get the sum 3. This is the maximum sum achievable in the range index 1 to 3.

For query 2, we need to select at least 1 element so we select -1 to get maximum sum -1.

Note :

The selected elements in the range L to R need not be consecutive. You can > select subsequence of integers to maximise the sum.

Constraints :

1<=N<=10^5
1<=Q<=10^5
-10^8 <= A[i] <= 10^8
1<=L<=R<=N
1<=X<=Y<=R-L+1

I tried to think of some approaches but could not find any algo for the above constraints. Any help/hint would be appreciated.


Solution

  • One approach is to preprocess the numbers by splitting into non-overlapping arrays of length L (for L equal to different powers of 2).

    Sort each array, and compute the cumulative sum of each array.

    Then for each query, identify the arrays which combine to make the query range and use bisection to identify the level T such that if taking all elements above T we end up with a legal number of elements and the highest sum.

    There will be log(N) arrays involved, and log(N) steps in each bisection, so this should be reasonably fast.

    (Note if our first evaluation shows that taking all positive elements ends up with too many, we need to find the lowest legal level by bisection, while if we end up with too few we need to find the highest legal level by bisection)

    Example

    Suppose we have an array A = [ 1, -1, 2, -2, 3, -3, 4, 0 ]. The preprocessing will split it into:

    Two arrays of length 4: [ 1, -1, 2, -2], [ 3, -3, 4, 0 ]
    Four arrays of length 2: [ 1, -1], [2, -2], [ 3, -3], [4, 0 ]
    Eight arrays of length 1: [1], [-1], [2], [-2], [ 3], [-3], [4], [0 ]
    

    Then with a query 3 to 5, we want the elements [-2,3,-3] which we can form from the arrays [-2] and [3,-3].

    Suppose we now want to find the maximum sum from at least 2 elements.

    We first try taking all positive elements, this only results in 1 element so we know we need to bisect for the highest legal level.

    The bisection could work by trying some values, e.g.

    All elements >= 0 gives 1 element, so value is too high
    All elements >= -4 gives 3 elements, so value is too low
    All elements >= -2 gives 2 elements, so value is just right