Given an array arr[] consisting of N integers, and a matrix Q[][] consisting of queries of the form (L, R, K), the task for each query is to calculate the sum of array elements from the range [L, R] which are present at indices(0- based indexing) which are multiples of K and
Examples:
Input: arr[]={1, 2, 3, 4, 5, 6}, Q[][]={{2, 5, 2}, {0, 5, 1}}
Output:
8
21
Explanation:
Query1: Indexes (2, 4) are multiple of K(= 2) from the range [2, 5]. Therefore, required Sum = 3+5 = 8.
Query2: Since all indices are a multiple of K(= 1), therefore, the required sum from the range [0, 5] = 1 + 2 + 3 + 4 + 5 + 6 = 21Input: arr[]={4, 3, 5, 1, 9}, Q[][]={{1, 4, 1}, {3, 4, 3}}
Output:
18
1
Approach: The problem can be solved using Prefix Sum Array and Range sum query technique. Follow the steps below to solve the problem:
- Initialize a matrix of size prefixSum[][] such that prefixSum[i][j] stores the sum of elements present in indices which are a multiple of i up to jth index.
- Traverse the array and precompute the prefix sums.
- Traverse each query, print the result of prefixSum[K][R] – prefixSum[K][L – 1].
Below is the implementation of the above approach:
// C++ Program to implement // the above appoach #include <bits/stdc++.h> using namespace std;
// Structure of a Query struct Node {
int L;
int R;
int K;
}; // Function to calculate the sum of array // elements at indices from range [L, R] // which are multiples of K for each query int kMultipleSum( int arr[], Node Query[],
int N, int Q)
{ // Stores Prefix Sum
int prefixSum[N + 1][N];
// prefixSum[i][j] : Stores the sum from
// indices [0, j] which are multiples of i
for ( int i = 1; i <= N; i++) {
prefixSum[i][0] = arr[0];
for ( int j = 0; j < N; j++) {
// If index j is a multiple of i
if (j % i == 0) {
// Compute prefix sum
prefixSum[i][j]
= arr[j] + prefixSum[i][j - 1];
}
// Otherwise
else {
prefixSum[i][j]
= prefixSum[i][j - 1];
}
}
}
// Traverse each query
for ( int i = 0; i < Q; i++) {
// Sum of all indices upto R which
// are a multiple of K
int last
= prefixSum[Query[i].K][Query[i].R];
int first;
// Sum of all indices upto L - 1 which
// are a multiple of K
if (Query[i].L == 0) {
first
= prefixSum[Query[i].K][Query[i].L];
}
else {
first
= prefixSum[Query[i].K][Query[i].L - 1];
}
// Calculate the difference
cout << last - first << endl;
}
} // Driver Code int main()
{ int arr[] = { 1, 2, 3, 4, 5, 6 };
int N = sizeof (arr) / sizeof (arr[0]);
int Q = 2;
Node Query[Q];
Query[0].L = 2, Query[0].R = 5, Query[0].K = 2;
Query[1].L = 3, Query[1].R = 5, Query[1].K = 5;
kMultipleSum(arr, Query, N, Q);
} |
// Java program to implement // the above appoach import java.util.*;
class GFG{
// Structure of a Query static class Node
{ int L;
int R;
int K;
}; // Function to calculate the sum of array // elements at indices from range [L, R] // which are multiples of K for each query static void kMultipleSum( int arr[], Node Query[],
int N, int Q)
{ // Stores Prefix Sum
int prefixSum[][] = new int [N + 1 ][N];
// prefixSum[i][j] : Stores the sum from
// indices [0, j] which are multiples of i
for ( int i = 1 ; i <= N; i++)
{
prefixSum[i][ 0 ] = arr[ 0 ];
for ( int j = 0 ; j < N; j++)
{
// If index j is a multiple of i
if (j % i == 0 )
{
// Compute prefix sum
if (j != 0 )
prefixSum[i][j] = arr[j] +
prefixSum[i][j - 1 ];
}
// Otherwise
else
{
prefixSum[i][j] = prefixSum[i][j - 1 ];
}
}
}
// Traverse each query
for ( int i = 0 ; i < Q; i++)
{
// Sum of all indices upto R which
// are a multiple of K
int last = prefixSum[Query[i].K][Query[i].R];
int first;
// Sum of all indices upto L - 1 which
// are a multiple of K
if (Query[i].L == 0 )
{
first = prefixSum[Query[i].K][Query[i].L];
}
else {
first = prefixSum[Query[i].K][Query[i].L - 1 ];
}
// Calculate the difference
System.out.print(last - first + "\n" );
}
} // Driver Code public static void main(String[] args)
{ int arr[] = { 1 , 2 , 3 , 4 , 5 , 6 };
int N = arr.length;
int Q = 2 ;
Node Query[] = new Node[Q];
for ( int i = 0 ; i < Q; i++)
Query[i] = new Node();
Query[ 0 ].L = 2 ;
Query[ 0 ].R = 5 ;
Query[ 0 ].K = 2 ;
Query[ 1 ].L = 3 ;
Query[ 1 ].R = 5 ;
Query[ 1 ].K = 5 ;
kMultipleSum(arr, Query, N, Q);
} } // This code is contributed by 29AjayKumar |
// C# program to implement // the above appoach using System;
class GFG{
// Structure of a Query class Node
{ public int L;
public int R;
public int K;
}; // Function to calculate the sum of array // elements at indices from range [L, R] // which are multiples of K for each query static void kMultipleSum( int []arr, Node []Query,
int N, int Q)
{ // Stores Prefix Sum
int [,]prefixSum = new int [N + 1, N];
// prefixSum[i,j] : Stores the sum from
// indices [0, j] which are multiples of i
for ( int i = 1; i <= N; i++)
{
prefixSum[i, 0] = arr[0];
for ( int j = 0; j < N; j++)
{
// If index j is a multiple of i
if (j % i == 0)
{
// Compute prefix sum
if (j != 0)
prefixSum[i, j] = arr[j] +
prefixSum[i, j - 1];
}
// Otherwise
else
{
prefixSum[i, j] = prefixSum[i, j - 1];
}
}
}
// Traverse each query
for ( int i = 0; i < Q; i++)
{
// Sum of all indices upto R which
// are a multiple of K
int last = prefixSum[Query[i].K,Query[i].R];
int first;
// Sum of all indices upto L - 1 which
// are a multiple of K
if (Query[i].L == 0)
{
first = prefixSum[Query[i].K,Query[i].L];
}
else
{
first = prefixSum[Query[i].K,Query[i].L - 1];
}
// Calculate the difference
Console.Write(last - first + "\n" );
}
} // Driver Code public static void Main(String[] args)
{ int []arr = { 1, 2, 3, 4, 5, 6 };
int N = arr.Length;
int Q = 2;
Node []Query = new Node[Q];
for ( int i = 0; i < Q; i++)
Query[i] = new Node();
Query[0].L = 2;
Query[0].R = 5;
Query[0].K = 2;
Query[1].L = 3;
Query[1].R = 5;
Query[1].K = 5;
kMultipleSum(arr, Query, N, Q);
} } // This code is contributed by 29AjayKumar |
8 6
Time Complexity: O(N2 + O(Q)), Computing the prefix sum array requires O(N2) computational complexity and each query requires O(1) computational complexity.
Auxiliary Space: O(N2)
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.