Skip to content
Related Articles

Related Articles

Improve Article

Queries to calculate sum of array elements present at every Yth index starting from the index X

  • Last Updated : 04 May, 2021

Given an array arr[] of size N, and an array Q[][] with each row representing a query of the form { X, Y }, the task for each query is to find the sum of array elements present at indices X, X + Y, X + 2 * Y + …

Examples:

Input: arr[] = { 1, 2, 7, 5, 4 }, Q[][] = { { 2, 1 }, { 3, 2 } } 
Output: 16 5 
Explanation: 
Query1: arr[2] + arr[2 + 1] + arr[2 + 2] = 7 + 5 + 4 = 16. 
Query2: arr[3] = 5.

Input: arr[] = { 3, 6, 1, 8, 0 } Q[][] = { { 0, 2 } } 
Output: 4

Naive Approach: The simplest approach to solve this problem is to traverse the array for each query and print the sum of arr[x] + arr[x + y] + arr[x + 2 * y] + …



Below is the implementation of above approach:

C++




// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to Find the sum of
// arr[x]+arr[x+y]+arr[x+2*y] + ...
// for all queries
void querySum(int arr[], int N,
              int Q[][2], int M)
{
 
    // Iterate over each query
    for (int i = 0; i < M; i++) {
 
        int x = Q[i][0];
        int y = Q[i][1];
 
        // Stores the sum of
        // arr[x]+arr[x+y]+arr[x+2*y] + ...
        int sum = 0;
 
        // Traverse the array and calculate
        // the sum of the expression
        while (x < N) {
 
            // Update sum
            sum += arr[x];
 
            // Update x
            x += y;
        }
 
        cout << sum << " ";
    }
}
 
// Driver Code
int main()
{
 
    int arr[] = { 1, 2, 7, 5, 4 };
    int Q[][2] = { { 2, 1 }, { 3, 2 } };
 
    int N = sizeof(arr) / sizeof(arr[0]);
 
    int M = sizeof(Q) / sizeof(Q[0]);
 
    querySum(arr, N, Q, M);
 
    return 0;
}

Java




// Java program for the above approach
import java.util.*;
 
class GFG{
 
// Function to Find the sum of
// arr[x]+arr[x+y]+arr[x+2*y] + ...
// for all queries
static void querySum(int arr[], int N,
                     int Q[][], int M)
{
     
    // Iterate over each query
    for(int i = 0; i < M; i++)
    {
        int x = Q[i][0];
        int y = Q[i][1];
         
        // Stores the sum of
        // arr[x]+arr[x+y]+arr[x+2*y] + ...
        int sum = 0;
 
        // Traverse the array and calculate
        // the sum of the expression
        while (x < N)
        {
             
            // Update sum
            sum += arr[x];
             
            // Update x
            x += y;
        }
        System.out.print(sum + " ");
    }
}
 
// Driver Code
public static void main(String[] args)
{
    int arr[] = { 1, 2, 7, 5, 4 };
    int Q[][] = { { 2, 1 }, { 3, 2 } };
 
    int N = arr.length;
    int M = Q.length;
 
    querySum(arr, N, Q, M);
}
}
 
// This code is contributed by 29AjayKumar

Python3




# Python3 program for the above approach
 
# Function to Find the sum of
# arr[x]+arr[x+y]+arr[x+2*y] + ...
# for all queries
def querySum(arr, N, Q, M):
 
    # Iterate over each query
    for i in range(M):
        x = Q[i][0]
        y = Q[i][1]
 
        # Stores the sum of
        # arr[x]+arr[x+y]+arr[x+2*y] + ...
        sum = 0
 
        # Traverse the array and calculate
        # the sum of the expression
        while (x < N):
 
            # Update sum
            sum += arr[x]
 
            # Update x
            x += y
        print(sum, end=" ")
 
# Driver Code
if __name__ == '__main__':
    arr = [ 1, 2, 7, 5, 4 ];
    Q = [ [ 2, 1 ], [3, 2 ] ]
    N = len(arr)
    M = len(Q)
    querySum(arr, N, Q, M)
 
    # This code is contributed by mohit kumar 29

C#




// C# program for the above approach
using System;
 
class GFG
{
 
  // Function to Find the sum of
  // arr[x]+arr[x+y]+arr[x+2*y] + ...
  // for all queries
  static void querySum(int []arr, int N,
                       int [,]Q, int M)
  {
 
    // Iterate over each query
    for(int i = 0; i < M; i++)
    {
      int x = Q[i, 0];
      int y = Q[i, 1];
 
      // Stores the sum of
      // arr[x]+arr[x+y]+arr[x+2*y] + ...
      int sum = 0;
 
      // Traverse the array and calculate
      // the sum of the expression
      while (x < N)
      {
 
        // Update sum
        sum += arr[x];
 
        // Update x
        x += y;
      }
      Console.Write(sum + " ");
    }
  }
 
  // Driver Code
  public static void Main(String[] args)
  {
    int []arr = { 1, 2, 7, 5, 4 };
    int [,]Q = { { 2, 1 }, { 3, 2 } };
    int N = arr.Length;
    int M = Q.GetLength(0);
    querySum(arr, N, Q, M);
  }
}
 
// This code is contributed by shikhasingrajput

Javascript




<script>
// JavaScript program for the above approach
 
// Function to Find the sum of
// arr[x]+arr[x+y]+arr[x+2*y] + ...
// for all queries
function querySum(arr, N, Q, M)
{
 
    // Iterate over each query
    for (let i = 0; i < M; i++) {
 
        let x = Q[i][0];
        let y = Q[i][1];
 
        // Stores the sum of
        // arr[x]+arr[x+y]+arr[x+2*y] + ...
        let sum = 0;
 
        // Traverse the array and calculate
        // the sum of the expression
        while (x < N) {
 
            // Update sum
            sum += arr[x];
 
            // Update x
            x += y;
        }
        document.write(sum + " ");
    }
}
 
// Driver Code
    let arr = [ 1, 2, 7, 5, 4 ];
    let Q = [ [ 2, 1 ], [ 3, 2 ] ];
    let N = arr.length;
    let M = Q.length;
    querySum(arr, N, Q, M);
 
// This code is contributed by Surbhi Tyagi.
</script>
Output: 
16 5

 

Time Complexity: O(|Q| * O(N)) 
Auxiliary Space: O(1)

Efficient Approach: The problem can be solved by precomputing the value of the given expression for all possible values of { X, Y } using Dynamic programming technique and Square Root Decomposition technique. Following are the recurrence relation:

if i + j < N
dp[i][j] = dp[i + j][j] + arr[i]
Otherwise, 
dp[i][j] = arr[i]

dp[i][j]: Stores the sum of the given expression where X = i, Y = j

Follow the steps below to solve the problem:

  • Initialize a 2D array, say dp[][], to store the sum of expression for all possible values of X and Y, where Y is less than or equal to sqrt(N).
  • Fill the dp[][] array using tabulation method.
  • Traverse the array Q[][]. For each query, check if the value of Q[i][1] is less than or equal to sqrt(N) or not. If found to be true, then print the value of dp[Q[i][0]][Q[i][1]].
  • Otherwise, calculate the value of the expression using the above naive approach and print the calculated value.

Below is the implementation of our approach:

C++




// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
const int sz = 20;
const int sqr = int(sqrt(sz)) + 1;
 
// Function to sum of arr[x]+arr[x+y]+arr[x+2*y] + ...
// for all possible values of X and Y, where Y is
// less than or equal to sqrt(N).
void precomputeExpressionForAllVal(int arr[], int N,
                                   int dp[sz][sqr])
{
 
    // Iterate over all possible values of X
    for (int i = N - 1; i >= 0; i--) {
 
        // Precompute for all possible values
        // of an expression such that y <= sqrt(N)
        for (int j = 1; j <= sqrt(N); j++) {
 
            // If i + j less than N
            if (i + j < N) {
 
                // Update dp[i][j]
                dp[i][j] = arr[i] + dp[i + j][j];
            }
            else {
 
                // Update dp[i][j]
                dp[i][j] = arr[i];
            }
        }
    }
}
 
// Function to Find the sum of
// arr[x]+arr[x+y]+arr[x+2*y] + ...
// for all queries
int querySum(int arr[], int N,
             int Q[][2], int M)
{
 
    // dp[x][y]: Stores sum of
    // arr[x]+arr[x+y]+arr[x+2*y] + ...
    int dp[sz][sqr];
 
    precomputeExpressionForAllVal(arr, N, dp);
    // Traverse the query array, Q[][]
    for (int i = 0; i < M; i++) {
 
        int x = Q[i][0];
        int y = Q[i][1];
 
        // If y is less than or equal
        // to sqrt(N)
        if (y <= sqrt(N)) {
            cout << dp[x][y] << " ";
            continue;
        }
 
        // Stores the sum of
        // arr[x]+arr[x+y]+arr[x+2*y] + ...
        int sum = 0;
 
        // Traverse the array, arr[]
        while (x < N) {
 
            // Update sum
            sum += arr[x];
 
            // Update x
            x += y;
        }
 
        cout << sum << " ";
    }
}
 
// Driver Code
int main()
{
 
    int arr[] = { 1, 2, 7, 5, 4 };
    int Q[][2] = { { 2, 1 }, { 3, 2 } };
 
    int N = sizeof(arr) / sizeof(arr[0]);
 
    int M = sizeof(Q) / sizeof(Q[0]);
 
    querySum(arr, N, Q, M);
    return 0;
}

Java




// Java program for the above approach
import java.util.*;
 
class GFG{
     
static int sz = 20;
static int sqr = (int)(Math.sqrt(sz)) + 1;
 
// Function to sum of arr[x]+arr[x+y]+arr[x+2*y] + ...
// for all possible values of X and Y, where Y is
// less than or equal to Math.sqrt(N).
static void precomputeExpressionForAllVal(int arr[],
                                          int N,
                                          int dp[][])
{
     
    // Iterate over all possible values of X
    for(int i = N - 1; i >= 0; i--)
    {
         
        // Precompute for all possible values
        // of an expression such that y <= Math.sqrt(N)
        for(int j = 1; j <= Math.sqrt(N); j++)
        {
             
            // If i + j less than N
            if (i + j < N)
            {
                 
                // Update dp[i][j]
                dp[i][j] = arr[i] + dp[i + j][j];
            }
            else
            {
                 
                // Update dp[i][j]
                dp[i][j] = arr[i];
            }
        }
    }
}
 
// Function to Find the sum of
// arr[x]+arr[x+y]+arr[x+2*y] + ...
// for all queries
static void querySum(int arr[], int N,
                     int Q[][], int M)
{
     
    // dp[x][y]: Stores sum of
    // arr[x]+arr[x+y]+arr[x+2*y] + ...
    int [][]dp = new int[sz][sqr];
 
    precomputeExpressionForAllVal(arr, N, dp);
     
    // Traverse the query array, Q[][]
    for(int i = 0; i < M; i++)
    {
        int x = Q[i][0];
        int y = Q[i][1];
 
        // If y is less than or equal
        // to Math.sqrt(N)
        if (y <= Math.sqrt(N))
        {
            System.out.print(dp[x][y] + " ");
            continue;
        }
         
        // Stores the sum of
        // arr[x]+arr[x+y]+arr[x+2*y] + ...
        int sum = 0;
 
        // Traverse the array, arr[]
        while (x < N)
        {
             
            // Update sum
            sum += arr[x];
 
            // Update x
            x += y;
        }
        System.out.print(sum + " ");
    }
}
 
// Driver Code
public static void main(String[] args)
{
    int arr[] = { 1, 2, 7, 5, 4 };
    int Q[][] = { { 2, 1 }, { 3, 2 } };
 
    int N = arr.length;
    int M = Q.length;
 
    querySum(arr, N, Q, M);
}
}
 
// This code is contributed by shikhasingrajput

Python3




# python program for the above approach
import math
sz = 20
sqr = int(math.sqrt(sz)) + 1
 
# Function to sum of arr[x]+arr[x+y]+arr[x+2*y] + ...
# for all possible values of X and Y, where Y is
# less than or equal to sqrt(N).
def precomputeExpressionForAllVal(arr, N, dp):
 
    # Iterate over all possible values of X
    for i in range(N - 1, -1, -1) :
       
        # Precompute for all possible values
        #  of an expression such that y <= sqrt(N)
        for j in range (1,int(math.sqrt(N)) + 1):
           
            # If i + j less than N
            if (i + j < N):
                 
                # Update dp[i][j]
                dp[i][j] = arr[i] + dp[i + j][j]
            else:
                 
                # Update dp[i][j]
                dp[i][j] = arr[i]
 
# Function to Find the sum of
# arr[x]+arr[x+y]+arr[x+2*y] + ...
# for all queries
def querySum(arr, N, Q,  M):
   
    # dp[x][y]: Stores sum of
    # arr[x]+arr[x+y]+arr[x+2*y] + ...
    dp = [ [0 for x in range(sz)]for x in range(sqr)]
    precomputeExpressionForAllVal(arr, N, dp)
     
    # Traverse the query array, Q[][]
    for i in range (0,M):
        x = Q[i][0]
        y = Q[i][1]
         
        # If y is less than or equal
        #  to sqrt(N)
        if (y <= math.sqrt(N)):
            print(dp[x][y])
            continue
             
        # Stores the sum of
        # arr[x]+arr[x+y]+arr[x+2*y] + ...
        sum = 0
         
        # Traverse the array, arr[]
        while (x < N):
           
            # Update sum
            sum += arr[x]
             
            # Update x
            x += y
        print(sum)
 
# Driver Code
arr = [ 1, 2, 7, 5, 4 ]
Q = [ [ 2, 1 ], [ 3, 2]]
 
N = len(arr)
 
M = len(Q[0])
querySum(arr, N, Q, M)
 
# This code is contributed by amreshkumar3.

C#




// C# program for the above approach
using System;
 
class GFG{
     
static int sz = 20;
static int sqr = (int)(Math.Sqrt(sz)) + 1;
 
// Function to sum of arr[x]+arr[x+y]+arr[x+2*y] + ...
// for all possible values of X and Y, where Y is
// less than or equal to Math.Sqrt(N).
static void precomputeExpressionForAllVal(int []arr,
                                          int N,
                                          int [,]dp)
{
     
    // Iterate over all possible values of X
    for(int i = N - 1; i >= 0; i--)
    {
         
        // Precompute for all possible values
        // of an expression such that y <= Math.Sqrt(N)
        for(int j = 1; j <= Math.Sqrt(N); j++)
        {
             
            // If i + j less than N
            if (i + j < N)
            {
                 
                // Update dp[i,j]
                dp[i, j] = arr[i] + dp[i + j, j];
            }
            else
            {
                 
                // Update dp[i,j]
                dp[i, j] = arr[i];
            }
        }
    }
}
 
// Function to Find the sum of
// arr[x]+arr[x+y]+arr[x+2*y] + ...
// for all queries
static void querySum(int []arr, int N,
                     int [,]Q, int M)
{
     
    // dp[x,y]: Stores sum of
    // arr[x]+arr[x+y]+arr[x+2*y] + ...
    int [,]dp = new int[sz, sqr];
 
    precomputeExpressionForAllVal(arr, N, dp);
     
    // Traverse the query array, Q[,]
    for(int i = 0; i < M; i++)
    {
        int x = Q[i, 0];
        int y = Q[i, 1];
         
        // If y is less than or equal
        // to Math.Sqrt(N)
        if (y <= Math.Sqrt(N))
        {
            Console.Write(dp[x, y] + " ");
            continue;
        }
         
        // Stores the sum of
        // arr[x]+arr[x+y]+arr[x+2*y] + ...
        int sum = 0;
 
        // Traverse the array, []arr
        while (x < N)
        {
             
            // Update sum
            sum += arr[x];
 
            // Update x
            x += y;
        }
        Console.Write(sum + " ");
    }
}
 
// Driver Code
public static void Main(String[] args)
{
    int []arr = { 1, 2, 7, 5, 4 };
    int [,]Q = { { 2, 1 }, { 3, 2 } };
 
    int N = arr.Length;
    int M = Q.GetLength(0);
 
    querySum(arr, N, Q, M);
}
}
 
// This code is contributed by shikhasingrajput

Javascript




<script>
// javascript program of the above approach
 
 let sz = 20;
 let sqr = (Math.sqrt(sz)) + 1;
 
// Function to sum of arr[x]+arr[x+y]+arr[x+2*y] + ...
// for all possible values of X and Y, where Y is
// less than or equal to Math.sqrt(N).
function precomputeExpressionForAllVal(arr, N, dp)
{
     
    // Iterate over all possible values of X
    for(let i = N - 1; i >= 0; i--)
    {
         
        // Precompute for all possible values
        // of an expression such that y <= Math.sqrt(N)
        for(let j = 1; j <= Math.sqrt(N); j++)
        {
             
            // If i + j less than N
            if (i + j < N)
            {
                 
                // Update dp[i][j]
                dp[i][j] = arr[i] + dp[i + j][j];
            }
            else
            {
                 
                // Update dp[i][j]
                dp[i][j] = arr[i];
            }
        }
    }
}
 
// Function to Find the sum of
// arr[x]+arr[x+y]+arr[x+2*y] + ...
// for all queries
function querySum(arr, N, Q, M)
{
    let dp = new Array(sz);
    // Loop to create 2D array using 1D array
    for (var i = 0; i < dp.length; i++) {
        dp[i] = new Array(2);
    }
     
    // Loop to create 2D array using 1D array
    for (var i = 0; i < dp.length; i++) {
        dp[i] = new Array(2);
    }
 
    precomputeExpressionForAllVal(arr, N, dp);
     
    // Traverse the query array, Q[][]
    for(let i = 0; i < M; i++)
    {
        let x = Q[i][0];
        let y = Q[i][1];
 
        // If y is less than or equal
        // to Math.sqrt(N)
        if (y <= Math.sqrt(N))
        {
            document.write(dp[x][y] + " ");
            continue;
        }
         
        // Stores the sum of
        // arr[x]+arr[x+y]+arr[x+2*y] + ...
        let sum = 0;
 
        // Traverse the array, arr[]
        while (x < N)
        {
             
            // Update sum
            sum += arr[x];
 
            // Update x
            x += y;
        }
        Sdocument.write(sum + " ");
    }
}
  
    // Driver Code
     
   // Given array
    let arr = [ 1, 2, 7, 5, 4 ];
    let Q= [[ 2, 1 ], [ 3, 2 ]]
 
    let N = arr.length;
    let M = Q.length;
 
    querySum(arr, N, Q, M);
  
 // This code is contributed by chinmoy1997pal.
</script>
Output: 
16 5

 

Time complexity: O(N * sqrt(N) + |Q| * sqrt(N)) 
Auxiliary Space:O(N * sqrt(N))

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.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.




My Personal Notes arrow_drop_up
Recommended Articles
Page :