Queries to calculate the Sum of Array elements in the range [L, R] having indices as multiple of K

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 = 21

Input: 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:



  1. 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.
  2. Traverse the array and precompute the prefix sums.
  3. Traverse each query, print the result of prefixSum[K][R] – prefixSum[K][L – 1].

Below is the implementation of the above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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);
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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

chevron_right


Output: 

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.




My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.



Improved By : 29AjayKumar