Range sum queries based on given conditions
Last Updated :
17 Jun, 2021
Given an array arr[] of N integers and matrix Queries[][] consisting of Q queries of the form {m, a, b}. For each query the task is to find the sum of array elements according to the following conditions:
- If m = 1: Find the sum of the array elements in the range [a, b].
- If m = 2: Rearrange the array elements in increasing order and find the sum of the elements in the range [a, b] in the new array.
Examples:
Input: arr[] = {6, 4, 2, 7, 2, 7}, Q = 3, Queries[][3] = {{2, 3, 6}, {1, 3, 4}, {1, 1, 6}}
Output: 24 9 28
Explanation:
For Query 1:
m is 2, then array after sorting is arr[] = {2, 2, 4, 6, 7, 7} and sum of element in the range [3, 6] is 4 + 6 + 7 + 7 = 24.
For Query 2:
m is 1, then original array is arr[] = {6, 4, 2, 7, 2, 7} and sum of element in the range [3, 4] is 2 + 7 = 9.
For Query 3:
m is 1, then original array is arr[] = {6, 4, 2, 7, 2, 7} and sum of element in the range [1, 6] is 6 + 4 + 2 + 7 + 2 + 7 = 28.
Input: arr[] = {5, 5, 2, 3}, Q = 3, Queries[][10] = {{1, 2, 4}, {2, 1, 4}, {1, 1, 1}, {2, 1, 4}, {2, 1, 2}, {1, 1, 1}, {1, 3, 3}, {1, 1, 3}, {1, 4, 4}, {1, 2, 2}}
Output: 10 15 5 15 5 5 2 12 3 5
Naive Approach: The idea is to traverse the given queries and find the sum of all the elements according to the given conditions:
- Choose the array according to the given m, if m is equal to 1 then choose the original array otherwise choose the other array where all the elements of the array arr[] are sorted.
- Now calculate the sum of the array between the range [a, b].
- Iterate a loop over the range to find the sum.
- Print the sum for each query.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int range_sum(vector< int > v, int a,
int b)
{
int sum = 0;
for ( int i = a - 1; i < b; i++) {
sum += v[i];
}
return sum;
}
void findSum(vector< int >& v1, int q,
int Queries[][3])
{
vector< int > v2;
int n = sizeof (v1) / sizeof ( int );
for ( int i = 0; i < n; i++) {
v2.push_back(v1[i]);
}
sort(v2.begin(), v2.end());
for ( int i = 0; i < q; i++) {
int m = Queries[i][0];
int a = Queries[i][1];
int b = Queries[i][2];
if (m == 1) {
cout << range_sum(v1, a, b)
<< ' ' ;
}
else if (m == 2) {
cout << range_sum(v2, a, b)
<< ' ' ;
}
}
}
int main()
{
vector< int > arr = { 6, 4, 2, 7, 2, 7 };
int Q = 1;
int Queries[][3] = { { 2, 3, 6 } };
findSum(arr, Q, Queries);
return 0;
}
|
Java
import java.util.*;
class GFG{
static int range_sum(Vector<Integer> v, int a,
int b)
{
int sum = 0 ;
for ( int i = a - 1 ; i < b; i++)
{
sum += v.get(i);
}
return sum;
}
static int range_sum( int []v, int a,
int b)
{
int sum = 0 ;
for ( int i = a - 1 ; i < b; i++)
{
sum += v[i];
}
return sum;
}
static void findSum( int []v1, int q,
int Queries[][])
{
Vector<Integer> v2 = new Vector<Integer>();
int n = v1.length;
for ( int i = 0 ; i < n; i++)
{
v2.add(v1[i]);
}
Collections.sort(v2);
for ( int i = 0 ; i < q; i++)
{
int m = Queries[i][ 0 ];
int a = Queries[i][ 1 ];
int b = Queries[i][ 2 ];
if (m == 1 )
{
System.out.print(range_sum(
v1, a, b) + " " );
}
else if (m == 2 )
{
System.out.print(range_sum(
v2, a, b) + " " );
}
}
}
public static void main(String[] args)
{
int []arr = { 6 , 4 , 2 , 7 , 2 , 7 };
int Q = 1 ;
int Queries[][] = { { 2 , 3 , 6 } };
findSum(arr, Q, Queries);
}
}
|
Python3
def range_sum(v, a, b):
Sum = 0
for i in range (a - 1 , b):
Sum + = v[i]
return Sum
def findSum(v1, q, Queries):
v2 = []
n = len (v1)
for i in range (n):
v2.append(v1[i])
v2.sort()
for i in range (q):
m = Queries[i][ 0 ]
a = Queries[i][ 1 ]
b = Queries[i][ 2 ]
if (m = = 1 ):
print (range_sum(v1, a, b), end = " " )
elif (m = = 2 ):
print (range_sum(v2, a, b), end = " " )
arr = [ 6 , 4 , 2 , 7 , 2 , 7 ]
Q = 1
Queries = [ [ 2 , 3 , 6 ] ]
findSum(arr, Q, Queries)
|
C#
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
class GFG{
static int range_sum(ArrayList v, int a,
int b)
{
int sum = 0;
for ( int i = a - 1; i < b; i++)
{
sum += ( int )v[i];
}
return sum;
}
static void findSum(ArrayList v1, int q,
int [,]Queries)
{
ArrayList v2 = new ArrayList();
int n = v1.Count;
for ( int i = 0; i < n; i++)
{
v2.Add(v1[i]);
}
v2.Sort();
for ( int i = 0; i < q; i++)
{
int m = Queries[i, 0];
int a = Queries[i, 1];
int b = Queries[i, 2];
if (m == 1)
{
Console.Write(range_sum(v1, a, b));
Console.Write( ' ' );
}
else if (m == 2)
{
Console.Write(range_sum(v2, a, b));
Console.Write( ' ' );
}
}
}
public static void Main( string [] args)
{
ArrayList arr= new ArrayList(){ 6, 4, 2,
7, 2, 7 };
int Q = 1;
int [,]Queries = { { 2, 3, 6 } };
findSum(arr, Q, Queries);
}
}
|
Javascript
<script>
function range_sum(v, a, b)
{
let sum = 0;
for (let i = a - 1; i < b; i++)
{
sum += v[i];
}
return sum;
}
function findSum(v1, q, Queries)
{
let v2 = [];
let n = v1.length;
for (let i = 0; i < n; i++)
{
v2.push(v1[i]);
}
v2.sort( function (a, b){ return a - b;});
for (let i = 0; i < q; i++)
{
let m = Queries[i][0];
let a = Queries[i][1];
let b = Queries[i][2];
if (m == 1)
{
document.write(range_sum(
v1, a, b) + " " );
}
else if (m == 2)
{
document.write(range_sum(
v2, a, b) + " " );
}
}
}
let arr = [ 6, 4, 2, 7, 2, 7 ];
let Q = 1;
let Queries = [ [ 2, 3, 6 ] ];
findSum(arr, Q, Queries);
</script>
|
Time Complexity: O(N2)
Auxiliary Space: O(N)
Efficient Approach: The above approach can be optimized by reducing one loop using the prefix sum array. Below are the steps:
- Create the other array brr[] to store the elements of the given array arr[] in sorted order.
- Find the prefix sum of both the arrays arr[] and brr[].
- Traverse the given queries and if the query is of type 1 then the sum of the element in the range [a, b] is given by:
arr[b – 1] – arr[a – 2]
- If the query is of type 2 then the sum of the element in the range [a, b] is given by:
brr[b – 1] – arr[a – 2]
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int range_sum(vector< int >& arr, int a,
int b)
{
int sum = 0;
if (a - 2 < 0)
sum = arr[b - 1];
else
sum = arr[b - 1] - arr[a - 2];
return sum;
}
void precompute_sum(vector< int >& arr,
vector< int >& brr)
{
int N = ( int )arr.size();
for ( int i = 1; i <= N; i++) {
arr[i] = arr[i] + arr[i - 1];
brr[i] = brr[i] + brr[i - 1];
}
}
void find_sum(vector< int >& arr, int q,
int Queries[][3])
{
vector< int > brr(arr);
int N = ( int )arr.size();
sort(brr.begin(), brr.end());
precompute_sum(arr, brr);
for ( int i = 0; i < q; i++) {
int m = Queries[i][0];
int a = Queries[i][1];
int b = Queries[i][2];
if (m == 1) {
cout << range_sum(arr, a, b)
<< ' ' ;
}
else if (m == 2) {
cout << range_sum(brr, a, b)
<< ' ' ;
}
}
}
int main()
{
vector< int > arr = { 0, 6, 4, 2, 7, 2, 7 };
int Q = 1;
int Queries[][3] = { { 2, 3, 6 } };
find_sum(arr, Q, Queries);
return 0;
}
|
Java
import java.util.*;
class GFG{
static int range_sum( int []arr, int a,
int b)
{
int sum = 0 ;
if (a - 2 < 0 )
sum = arr[b - 1 ];
else
sum = arr[b - 1 ] - arr[a - 2 ];
return sum;
}
static void precompute_sum( int []arr,
int []brr)
{
int N = ( int )arr.length;
for ( int i = 1 ; i < N; i++)
{
arr[i] = arr[i] + arr[i - 1 ];
brr[i] = brr[i] + brr[i - 1 ];
}
}
static void find_sum( int []arr, int q,
int Queries[][])
{
int []brr = arr.clone();
int N = ( int )arr.length;
Arrays.sort(brr);
precompute_sum(arr, brr);
for ( int i = 0 ; i < q; i++)
{
int m = Queries[i][ 0 ];
int a = Queries[i][ 1 ];
int b = Queries[i][ 2 ];
if (m == 1 )
{
System.out.print(range_sum(
arr, a, b) + " " );
}
else if (m == 2 )
{
System.out.print(range_sum(
brr, a, b) + " " );
}
}
}
public static void main(String[] args)
{
int []arr = { 0 , 6 , 4 , 2 , 7 , 2 , 7 };
int Q = 1 ;
int Queries[][] = { { 2 , 3 , 6 } };
find_sum(arr, Q, Queries);
}
}
|
Python3
def range_sum(arr, a, b):
sum = 0
if (a - 2 < 0 ):
sum = arr[b - 1 ]
else :
sum = (arr[b - 1 ] -
arr[a - 2 ])
return sum
def precompute_sum(arr, brr):
N = len (arr)
for i in range ( 1 , N):
arr[i] = arr[i] + arr[i - 1 ]
brr[i] = brr[i] + brr[i - 1 ]
def find_sum(arr, q, Queries):
brr = arr.copy()
N = len (arr)
brr.sort()
precompute_sum(arr, brr)
for i in range (q):
m = Queries[i][ 0 ]
a = Queries[i][ 1 ]
b = Queries[i][ 2 ]
if (m = = 1 ):
print (range_sum(arr,
a, b),
end = ' ' )
elif (m = = 2 ):
print (range_sum(brr,
a, b),
end = ' ' )
if __name__ = = "__main__" :
arr = [ 0 , 6 , 4 ,
2 , 7 , 2 , 7 ]
Q = 1
Queries = [[ 2 , 3 , 6 ]]
find_sum(arr, Q, Queries)
|
C#
using System;
class GFG{
static int range_sum( int []arr,
int a,
int b)
{
int sum = 0;
if (a - 2 < 0)
sum = arr[b - 1];
else
sum = arr[b - 1] - arr[a - 2];
return sum;
}
static void precompute_sum( int []arr,
int []brr)
{
int N = ( int )arr.Length;
for ( int i = 1; i < N; i++)
{
arr[i] = arr[i] + arr[i - 1];
brr[i] = brr[i] + brr[i - 1];
}
}
static void find_sum( int []arr, int q,
int [,]Queries)
{
int []brr = new int [arr.Length];
arr.CopyTo(brr, 0);
int N = ( int )arr.Length;
Array.Sort(brr);
precompute_sum(arr, brr);
for ( int i = 0; i < q; i++)
{
int m = Queries[i, 0];
int a = Queries[i, 1];
int b = Queries[i, 2];
if (m == 1)
{
Console.Write(range_sum(
arr, a, b) + " " );
}
else if (m == 2)
{
Console.Write(range_sum(
brr, a, b) + " " );
}
}
}
public static void Main(String[] args)
{
int []arr = {0, 6, 4, 2, 7, 2, 7};
int Q = 1;
int [,]Queries = {{2, 3, 6}};
find_sum(arr, Q, Queries);
}
}
|
Javascript
<script>
function range_sum(arr,a,b)
{
let sum = 0;
if (a - 2 < 0)
sum = arr[b - 1];
else
sum = arr[b - 1] - arr[a - 2];
return sum;
}
function precompute_sum(arr,brr)
{
let N = arr.length;
for (let i = 1; i < N; i++)
{
arr[i] = arr[i] + arr[i - 1];
brr[i] = brr[i] + brr[i - 1];
}
}
function find_sum(arr,q,Queries)
{
let brr = [...arr];
let N = arr.length;
brr.sort( function (a,b){ return a-b;});
precompute_sum(arr, brr);
for (let i = 0; i < q; i++)
{
let m = Queries[i][0];
let a = Queries[i][1];
let b = Queries[i][2];
if (m == 1)
{
document.write(range_sum(
arr, a, b) + " " );
}
else if (m == 2)
{
document.write(range_sum(
brr, a, b) + " " );
}
}
}
let arr=[0, 6, 4, 2, 7, 2, 7];
let Q = 1;
let Queries = [[ 2, 3, 6 ]];
find_sum(arr, Q, Queries);
</script>
|
Time Complexity: O(N*log N)
Auxiliary Space: O(N)
Share your thoughts in the comments
Please Login to comment...