Open In App

Total Oranges Collection between Given Tree Positions

Last Updated : 12 Jan, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

Given n trees arranged in linear order. The position of trees and oranges contained by a tree is represented by 2D integer array trees[] where ‘trees[i] = {x, y}’ represents that a tree exists on position ‘x’ and it contains ‘y’ oranges on it. There are also q queries[] where queries[i] = {left, right}. For each query, we need to find out the total number of oranges we can collect between left and right.

Note: The position of x can vary between 0 to 1000.

Examples:

Input: trees[][] = { {1, 2}, {3, 2}, {4, 5}, {7, 1}, {10, 4} }, queries[] = { {0, 12}, {4, 6}, {2, 8} }
Output: 14 5 8
Explanation: queries[0]: We can collect oranges from all trees i.e. 2 + 2 + 5 + 1 + 4 = 14
queries[1]: Oranges from 3nd tree only be collected.
queries[2]: We can collect oranges from 2nd, 3rd and 4th tree i.e. 2 + 5 + 1 = 8

Approach: This can be solved with the following idea:

By updating maximum and minimum location and creating the vector of that length. Updating number of oranges at each location and creating a prefix array. While calculating the orange between ranges by seeing their location and difference between them.

Below are the steps involved:

  • Update max and min location:
    • By seeing location of trees and update in maxx and minn variable.
  • Create a vector v of length maxx + 1:
    • Store the number of oranges in each location.
  • After this step, create a prefix array of the oranges store in vector v:
    • v[i] = v[i] + v[i – 1], prefix array where at each index sum of all oranges is there.
  • Iterate in queries array:
    • From vector v calculate number of oranges between v[left] and v[right].
    • Add the v[right] – v[left] in res.
  • Return res.

Below is the implementation of the code:

C++




// C++ Implementation
#include <bits/stdc++.h>
#include <iostream>
using namespace std;
 
// Function to calculate number of oranges
// between ranges
vector<long long>
collectMaximumOranges(int n, int q,
                      vector<vector<int> > trees,
                      vector<vector<int> > queries)
{
 
    int i = 0;
 
    // Intialize max and min location
    // on a straight line
    long long maxx = LLONG_MIN;
    long long minn = LLONG_MAX;
    while (i < n) {
 
        long long loc = trees[i][0];
        long long oranges = trees[i][1];
 
        // Update values
        maxx = max(maxx, loc);
        minn = min(minn, loc);
        i++;
    }
 
    // Add oranges in vector
    i = 0;
    long long v[maxx + 1] = { 0 };
    while (i < n) {
        long long loc = trees[i][0];
        long long oranges = trees[i][1];
        v[loc] = oranges;
        i++;
    }
    i = minn;
    i++;
 
    // Sum up the values
    while (i <= maxx) {
        v[i] = v[i] + v[i - 1];
        i++;
    }
    i = 0;
 
    vector<long long> res;
 
    // Iterate in queries
    while (i < q) {
        long long start = queries[i][0];
        long long end = queries[i][1];
        long long left = 0;
        long long right = 0;
 
        // Calculate values with in range
        if (start > maxx) {
            left = v[maxx];
        }
        else if (start - 1 >= 0) {
            left = v[start - 1];
        }
        if (end > maxx) {
            right = v[maxx];
        }
        else if (end < 0) {
            right = 0;
        }
        else {
            right = v[end];
        }
 
        // Add it to res vector
        res.push_back(right - left);
 
        i++;
    }
 
    // Return res
    return res;
}
 
// Driver code
int main()
{
 
    int n = 5;
    int q = 3;
 
    vector<vector<int> > trees = {
        { 1, 2 }, { 3, 2 }, { 4, 5 }, { 7, 1 }, { 10, 4 }
    };
    vector<vector<int> > queries
        = { { 0, 12 }, { 4, 6 }, { 2, 8 } };
 
    // Function call
    vector<long long> res
        = collectMaximumOranges(n, q, trees, queries);
 
    // Print the res
    for (auto a : res) {
        cout << a << " ";
    }
    return 0;
}


Java




import java.util.ArrayList;
import java.util.List;
 
public class Main {
    // Function to calculate number of oranges between ranges
    static ArrayList<Long> collectMaximumOranges(int n, int q, ArrayList<ArrayList<Integer>> trees,
                                                  ArrayList<ArrayList<Integer>> queries) {
 
        int i = 0;
 
        // Initialize max and min location on a straight line
        long maxx = Long.MIN_VALUE;
        long minn = Long.MAX_VALUE;
        while (i < n) {
 
            long loc = trees.get(i).get(0);
            long oranges = trees.get(i).get(1);
 
            // Update values
            maxx = Math.max(maxx, loc);
            minn = Math.min(minn, loc);
            i++;
        }
 
        // Add oranges in vector
        i = 0;
        long[] v = new long[(int) (maxx + 1)];
        while (i < n) {
            long loc = trees.get(i).get(0);
            long oranges = trees.get(i).get(1);
            v[(int) loc] = oranges;
            i++;
        }
        i = (int) minn + 1;
 
        // Sum up the values
        while (i <= maxx) {
            v[i] = v[i] + v[i - 1];
            i++;
        }
        i = 0;
 
        ArrayList<Long> res = new ArrayList<>();
 
        // Iterate in queries
        while (i < q) {
            long start = queries.get(i).get(0);
            long end = queries.get(i).get(1);
            long left = 0;
            long right = 0;
 
            // Calculate values within range
            if (start > maxx) {
                left = v[(int) maxx];
            } else if (start - 1 >= 0) {
                left = v[(int) (start - 1)];
            }
            if (end > maxx) {
                right = v[(int) maxx];
            } else if (end < 0) {
                right = 0;
            } else {
                right = v[(int) end];
            }
 
            // Add it to res list
            res.add(right - left);
 
            i++;
        }
 
        // Return res
        return res;
    }
 
    // Driver code
    public static void main(String[] args) {
 
        int n = 5;
        int q = 3;
 
        ArrayList<ArrayList<Integer>> trees = new ArrayList<>();
        trees.add(new ArrayList<>(List.of(1, 2)));
        trees.add(new ArrayList<>(List.of(3, 2)));
        trees.add(new ArrayList<>(List.of(4, 5)));
        trees.add(new ArrayList<>(List.of(7, 1)));
        trees.add(new ArrayList<>(List.of(10, 4)));
 
        ArrayList<ArrayList<Integer>> queries = new ArrayList<>();
        queries.add(new ArrayList<>(List.of(0, 12)));
        queries.add(new ArrayList<>(List.of(4, 6)));
        queries.add(new ArrayList<>(List.of(2, 8)));
 
        // Function call
        ArrayList<Long> res = collectMaximumOranges(n, q, trees, queries);
 
        for (long a : res) {
            System.out.print(a + " ");
        }
    }
}


Python3




def collect_maximum_oranges(n, q, trees, queries):
    # Find maximum and minimum locations
    maxx = float('-inf')
    minn = float('inf')
 
    # Loop to find max and min locations
    for loc, oranges in trees:
        maxx = max(maxx, loc)
        minn = min(minn, loc)
 
    # Initialize a list to store oranges at each location
    v = [0] * (maxx + 1)
 
    # Store oranges at respective locations
    for loc, oranges in trees:
        v[loc] = oranges
 
    # Calculate cumulative oranges at each location
    i = minn + 1
    while i <= maxx:
        v[i] = v[i] + v[i - 1]
        i += 1
 
    # Initialize a list to store results
    res = []
 
    # Calculate oranges in each query range
    for start, end in queries:
        left, right = 0, 0
 
        # Calculate oranges on the left side of the range
        if start > maxx:
            left = v[maxx]
        elif start - 1 >= 0:
            left = v[start - 1]
 
        # Calculate oranges on the right side of the range
        if end > maxx:
            right = v[maxx]
        elif end < 0:
            right = 0
        else:
            right = v[end]
 
        # Append the difference to results
        res.append(right - left)
 
    # Return the results
    return res
 
# Driver code
n = 5
q = 3
 
trees = [
    [1, 2], [3, 2], [4, 5], [7, 1], [10, 4]
]
queries = [
    [0, 12], [4, 6], [2, 8]
]
 
# Function call
res = collect_maximum_oranges(n, q, trees, queries)
 
# Print the res
for a in res:
    print(a, end=' ')


C#




using System;
using System.Collections.Generic;
 
class Program
{
    // Function to calculate number of oranges between ranges
    static List<long> CollectMaximumOranges(int n, int q, List<List<int>> trees, List<List<int>> queries)
    {
        int i = 0;
 
        // Intialize max and min location on a straight line
        long maxx = long.MinValue;
        long minn = long.MaxValue;
 
        while (i < n)
        {
            long loc = trees[i][0];
            long oranges = trees[i][1];
 
            // Update values
            maxx = Math.Max(maxx, loc);
            minn = Math.Min(minn, loc);
            i++;
        }
 
        // Add oranges in vector
        i = 0;
        long[] v = new long[maxx + 1];
        while (i < n)
        {
            long loc = trees[i][0];
            long oranges = trees[i][1];
            v[loc] = oranges;
            i++;
        }
 
        i = (int)minn;
        i++;
 
        // Sum up the values
        while (i <= maxx)
        {
            v[i] = v[i] + v[i - 1];
            i++;
        }
 
        i = 0;
        List<long> res = new List<long>();
 
        // Iterate in queries
        while (i < q)
        {
            long start = queries[i][0];
            long end = queries[i][1];
            long left = 0;
            long right = 0;
 
            // Calculate values within range
            if (start > maxx)
            {
                left = v[maxx];
            }
            else if (start - 1 >= 0)
            {
                left = v[start - 1];
            }
 
            if (end > maxx)
            {
                right = v[maxx];
            }
            else if (end < 0)
            {
                right = 0;
            }
            else
            {
                right = v[end];
            }
 
            // Add it to res vector
            res.Add(right - left);
            i++;
        }
 
        // Return res
        return res;
    }
 
    // Driver code
    static void Main()
    {
        int n = 5;
        int q = 3;
 
        List<List<int>> trees = new List<List<int>>
        {
            new List<int> {1, 2},
            new List<int> {3, 2},
            new List<int> {4, 5},
            new List<int> {7, 1},
            new List<int> {10, 4}
        };
 
        List<List<int>> queries = new List<List<int>>
        {
            new List<int> {0, 12},
            new List<int> {4, 6},
            new List<int> {2, 8}
        };
 
        // Function call
        List<long> res = CollectMaximumOranges(n, q, trees, queries);
 
        // Print the res
        foreach (var a in res)
        {
            Console.Write(a + " ");
        }
    }
}


Javascript




// Function to collect maximum oranges based on given trees and queries
function collectMaximumOranges(n, q, trees, queries) {
    // Initializing variables
    let i = 0;
    let maxx = Number.MIN_SAFE_INTEGER; // Variable to store the maximum x-coordinate
    let minn = Number.MAX_SAFE_INTEGER; // Variable to store the minimum x-coordinate
 
    // Finding the maximum and minimum x-coordinates among the trees
    while (i < n) {
        let loc = trees[i][0];
        let oranges = trees[i][1];
        maxx = Math.max(maxx, loc);
        minn = Math.min(minn, loc);
        i++;
    }
 
    // Resetting the loop variable
    i = 0;
    // Initializing an array to store oranges at each x-coordinate
    let v = new Array(maxx + 1).fill(0);
    // Populating the array with oranges at each x-coordinate
    while (i < n) {
        let loc = trees[i][0];
        let oranges = trees[i][1];
        v[loc] = oranges;
        i++;
    }
 
    // Resetting the loop variable to update the array with cumulative sum
    i = minn + 1;
    // Updating the array with cumulative sum of oranges at each x-coordinate
    while (i <= maxx) {
        v[i] = v[i] + v[i - 1];
        i++;
    }
 
    // Resetting the loop variable
    i = 0;
    // Array to store the result of each query
    let res = [];
    // Processing each query
    while (i < q) {
        let start = queries[i][0];
        let end = queries[i][1];
        let left = 0;
        let right = 0;
 
        // Calculating cumulative sum of oranges from the array based on query range
        if (start > maxx) {
            left = v[maxx];
        } else if (start - 1 >= 0) {
            left = v[start - 1];
        }
        if (end > maxx) {
            right = v[maxx];
        } else if (end < 0) {
            right = 0;
        } else {
            right = v[end];
        }
 
        // Adding the result of the current query to the result array
        res.push(right - left);
        i++;
    }
 
    // Returning the final result array
    return res;
}
 
// Driver Code
let n = 5;
let q = 3;
let trees = [[1, 2], [3, 2], [4, 5], [7, 1], [10, 4]];
let queries = [[0, 12], [4, 6], [2, 8]];
 
let res = collectMaximumOranges(n, q, trees, queries);
console.log(res.join(" "));


Output

14 5 8 






Time Complexity: O(N*log N)
Auxiliary Space: O(N)



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads