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