Open In App

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

Last Updated : 02 May, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

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

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

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 <bits/stdc++.h>
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)



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads