GFG App
Open App
Browser
Continue

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

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 the above approach:

## C++

 // C++ program for the above approach #include 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



Output:

16 5

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

### Approach 2A: Using Dynamic programming technique and Square Root Decomposition technique

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 the Square Root Decomposition technique. The 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:

1. 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).
2. Fill the dp[][] array using tabulation method.
3. 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]].
4. 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 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



Output:

16 5

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

### Approach 2B: Space optimization

In the previous approach, we can see that in the function precomputeExpressionForAllVal we use 2d dp which is not required because dp[i][j] is dependent upon arr[i] and dp[i + j][j] so we can optimize its space complexity by using 1d DP.

Implementation:

1. Initialize dp to all zeros and Iterate over all possible values of X from N-1 down to 0.
2. Precompute for all possible values of an expression such that y <= sqrt(N).
3. If i + j is less than N, update dp[i] to add arr[i+j].
4. Define the function querySum to take in the input parameters arr, N, Q, and M.
5. Traverse the query array Q[][], where each query is represented by a pair of integers {x, y}.
6. If y is less than or equal to sqrt(N), iterate over arr[x], arr[x+y], arr[x+2y],…, until the end of the array and print their sum.
7. Otherwise, for each query, initialize sum to zero and traverse the array arr[] starting from index x and incrementing by y.
8. Add each element arr[i] to sum until x is less than N.
9. Print the final sum for each query.

Example:

## C++

 #include using namespace std;   // 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[]) {       // 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] += arr[i + j];             }         }     } }   // 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) {       // 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)) {             int ans = 0;             for (int j = x; j < N; j += y)                 ans += arr[j];             cout << ans << " ";             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]);       // dp[x]: Stores 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).     int dp[N] = { 0 };     precomputeExpressionForAllVal(arr, N, dp);       querySum(arr, N, Q, M);       return 0; }   // this code is contributed by bhardwajji

## Java

 import java.util.*;   public class Main {     // 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).     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 <= 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] += arr[i + j];                 }             }         }     }       // 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)     {           // 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 <= Math.sqrt(N)) {                 int ans = 0;                 for (int j = x; j < N; j += y)                     ans += arr[j];                 System.out.print(ans + " ");                 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;           // dp[x]: Stores 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).         int[] dp = new int[N];         precomputeExpressionForAllVal(arr, N, dp);           querySum(arr, N, Q, M);     } }

## Python3

 import math     def precompute_expression_for_all_val(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] += arr[i + j]     def query_sum(arr, N, Q, M):     # Traverse the query array, Q[][]     for i in range(M):           x = Q[i][0]         y = Q[i][1]           # If y is less than or equal         # to sqrt(N)         if y <= int(math.sqrt(N)):             ans = 0             for j in range(x, N, y):                 ans += arr[j]             print(ans, end=" ")             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, end=" ")     # Driver Code arr = [1, 2, 7, 5, 4] Q = [[2, 1], [3, 2]] N = len(arr) M = len(Q)   # dp[x]: Stores 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). dp = [0] * N precompute_expression_for_all_val(arr, N, dp)   query_sum(arr, N, Q, M)

## C#

 // C# implementation of the above code using System;   class Program {     static void PrecomputeExpressionForAllVal(int[] arr,                                               int N,                                               int[] dp)     {         for (int i = N - 1; i >= 0; i--) {             for (int j = 1; j <= Math.Sqrt(N); j++) {                 if (i + j < N) {                     dp[i] += arr[i + j];                 }             }         }     }     static void QuerySum(int[] arr, int N, int[][] Q, int M)     {         for (int i = 0; i < M; i++) {             int x = Q[i][0];             int y = Q[i][1];             if (y <= Math.Sqrt(N)) {                 int ans = 0;                 for (int j = x; j < N; j += y) {                     ans += arr[j];                 }                 Console.Write(ans + " ");                 continue;             }             int sum = 0;             while (x < N) {                 sum += arr[x];                 x += y;             }             Console.Write(sum + " ");         }     }       static void Main(string[] args)     {         int[] arr = { 1, 2, 7, 5, 4 };         int[][] Q             = { new int[] { 2, 1 }, new int[] { 3, 2 } };         int N = arr.Length;         int M = Q.Length;         int[] dp = new int[N];         PrecomputeExpressionForAllVal(arr, N, dp);         QuerySum(arr, N, Q, M);     } } // This code is contributed by user_dtewbxkn77n

## Javascript

 // JavaScript implementation of the above code function precomputeExpressionForAllVal(arr, N) { const dp = new Array(N).fill(0); for (let i = N - 1; i >= 0; i--) { for (let j = 1; j <= Math.sqrt(N); j++) { if (i + j < N) { dp[i] += arr[i + j]; } } } return dp; }   function querySum(arr, N, Q, M) { for (let i = 0; i < M; i++) { const x = Q[i][0]; const y = Q[i][1]; if (y <= Math.sqrt(N)) { let ans = 0; for (let j = x; j < N; j += y) { ans += arr[j]; } console.log(ans + " "); continue; } let sum = 0; while (x < N) { sum += arr[x]; x += y; } console.log(sum + " "); } }   const arr = [1, 2, 7, 5, 4]; const Q = [ [2, 1], [3, 2] ]; const N = arr.length; const M = Q.length; const dp = precomputeExpressionForAllVal(arr, N); querySum(arr, N, Q, M);

Output:

16 5

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

My Personal Notes arrow_drop_up