Open In App

Queries to calculate sum of array elements consisting of odd number of divisors

Last Updated : 23 Apr, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given an array arr[] consisting of N positive integers and an array Query[][2] consisting of Q queries of the form {L, R}, the task is to find the sum of all array elements from the range [L, R], having odd number of divisors.

Examples:

Input: arr[] = {2, 4, 5, 6, 9}, Q = 3, Query[][] = {{0, 2}, {1, 3}, {1, 4}} 
Output: 4 4 13 
Explanation: 
Query 1: Elements from indices [0, 2] are {2, 4, 5}. Out of them, only 4 has odd number of divisors. Therefore, the sum is 4.
Query 2: Elements from indices [1, 3] are {4, 5, 6}. Out of them, only 4 has odd number of divisors. Therefore, the sum is 4.
Query 3: Elements from the indices [1, 4] are {4, 5, 6, 9}. Out of them, only 4, 9 has odd number of divisors. Therefore, the sum is 13.

Input: arr[] = {1, 16, 5, 4, 9}, Q = 2, Query[][] = {{1, 3}, {0, 2}} 
Output: 20 17 

Naive Approach: The simplest approach is to solve the given problem is to traverse the given array arr[] over the range [L, R] for each query and find the sum of elements in the range [L, R] having odd numbers of divisors, and print the resultant sum.

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

Efficient Approach: The above approach can also be optimized which is based on the below observation:

Follow the steps below to solve the problem:

Below is the implementation of the above approach: 

C++




// C++ program for the above approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Function to get the middle index
// from the given ranges
int getMid(int s, int e)
{
    return s + (e - s) / 2;
}
 
// Recursive function to find the sum
// of values in the given range of
// the array
int getSumUtil(int* st, int ss, int se,
               int qs, int qe, int si)
{
 
    // If segment of this node is a
    // part of given range, then
    // return the sum of the segment
    if (qs <= ss && qe >= se)
        return st[si];
 
    // If segment of this node is
    // outside the given range
    if (se < qs || ss > qe)
        return 0;
 
    // If a part of this segment
    // overlaps the given range
    int mid = getMid(ss, se);
 
    return getSumUtil(st, ss, mid,
                      qs, qe, 2 * si + 1)
           + getSumUtil(st, mid + 1,
                        se, qs, qe,
                        2 * si + 2);
}
 
// Function to find the sum of elements
// in the range from index qs (query
// start) to qe (query end)
int getSum(int* st, int n, int qs, int qe)
{
    // Invalid ranges
    if (qs < 0 || qe > n - 1 || qs > qe) {
        cout << "Invalid Input";
        return -1;
    }
 
    return getSumUtil(st, 0, n - 1, qs, qe, 0);
}
 
// Recursive function to construct the
// Segment Tree for array[ss..se]. si
// is index of current node in tree st
int constructSTUtil(int arr[], int ss,
                    int se, int* st,
                    int si)
{
    // If there is one element
    // in the array
    if (ss == se) {
        st[si] = arr[ss];
        return arr[ss];
    }
 
    int mid = getMid(ss, se);
 
    // Recur for left and right
    // subtrees and store the sum
    // of values in this node
    st[si] = constructSTUtil(arr, ss, mid,
                             st, si * 2 + 1)
             + constructSTUtil(arr, mid + 1,
                               se, st,
                               si * 2 + 2);
    return st[si];
}
 
// Function to construct segment tree
// from the given array
int* constructST(int arr[], int n)
{
    // Allocate memory for the segment
    // tree Height of segment tree
    int x = (int)(ceil(log2(n)));
 
    // Maximum size of segment tree
    int max_size = 2 * (int)pow(2, x) - 1;
 
    // Allocate memory
    int* st = new int[max_size];
 
    // Fill the allocated memory st
    constructSTUtil(arr, 0, n - 1, st, 0);
 
    // Return the constructed
    // segment tree
    return st;
}
 
// Function to find the sum of elements
// having odd number of divisors in
// index range [L, R] for Q queries
void OddDivisorsSum(int n, int q, int arr[],
                    vector<pair<int, int> > Query)
{
    // Traverse the array, arr[]
    for (int i = 0; i < n; i++) {
        int sq = sqrt(arr[i]);
 
        // Replace elements that are
        // not perfect squares with 0
        if (sq * sq != arr[i])
            arr[i] = 0;
    }
 
    // Build segment tree from the
    // given array
    int* st = constructST(arr, n);
 
    // Iterate through all the queries
    for (int i = 0; i < q; i++) {
        int l = Query[i].first;
        int r = Query[i].second;
 
        // Print sum of values in
        // array from index l to r
        cout << getSum(st, n, l, r) << " ";
    }
}
 
// Driver Code
int main()
{
    int arr[] = { 2, 4, 5, 6, 9 };
    int N = sizeof(arr) / sizeof(arr[0]);
    int Q = 3;
    vector<pair<int, int> > Query
        = { { 0, 2 }, { 1, 3 }, { 1, 4 } };
    OddDivisorsSum(N, Q, arr, Query);
 
    return 0;
}


Java




// java program for the above approach
import java.io.*;
import java.lang.*;
import java.util.*;
 
public class GFG {
 
    // Function to get the middle index
    // from the given ranges
    static int getMid(int s, int e)
    {
        return s + (e - s) / 2;
    }
 
    // Recursive function to find the sum
    // of values in the given range of
    // the array
    static int getSumUtil(int st[], int ss, int se, int qs,
                          int qe, int si)
    {
 
        // If segment of this node is a
        // part of given range, then
        // return the sum of the segment
        if (qs <= ss && qe >= se)
            return st[si];
 
        // If segment of this node is
        // outside the given range
        if (se < qs || ss > qe)
            return 0;
 
        // If a part of this segment
        // overlaps the given range
        int mid = getMid(ss, se);
 
        return getSumUtil(st, ss, mid, qs, qe, 2 * si + 1)
            + getSumUtil(st, mid + 1, se, qs, qe,
                         2 * si + 2);
    }
 
    // Function to find the sum of elements
    // in the range from index qs (query
    // start) to qe (query end)
    static int getSum(int st[], int n, int qs, int qe)
    {
        // Invalid ranges
        if (qs < 0 || qe > n - 1 || qs > qe) {
            System.out.println("Invalid Input");
            return -1;
        }
 
        return getSumUtil(st, 0, n - 1, qs, qe, 0);
    }
 
    // Recursive function to construct the
    // Segment Tree for array[ss..se]. si
    // is index of current node in tree st
    static int constructSTUtil(int arr[], int ss, int se,
                               int st[], int si)
    {
        // If there is one element
        // in the array
        if (ss == se) {
            st[si] = arr[ss];
            return arr[ss];
        }
 
        int mid = getMid(ss, se);
 
        // Recur for left and right
        // subtrees and store the sum
        // of values in this node
        st[si]
            = constructSTUtil(arr, ss, mid, st, si * 2 + 1)
              + constructSTUtil(arr, mid + 1, se, st,
                                si * 2 + 2);
        return st[si];
    }
 
    // Function to construct segment tree
    // from the given array
    static int[] constructST(int arr[], int n)
    {
        // Allocate memory for the segment
        // tree Height of segment tree
        int x = (int)(Math.ceil(Math.log(n) / Math.log(2)));
 
        // Maximum size of segment tree
        int max_size = 2 * (int)Math.pow(2, x) - 1;
 
        // Allocate memory
        int st[] = new int[max_size];
 
        // Fill the allocated memory st
        constructSTUtil(arr, 0, n - 1, st, 0);
 
        // Return the constructed
        // segment tree
        return st;
    }
 
    // Function to find the sum of elements
    // having odd number of divisors in
    // index range [L, R] for Q queries
    static void OddDivisorsSum(int n, int q, int arr[],
                               int Query[][])
    {
        // Traverse the array, arr[]
        for (int i = 0; i < n; i++) {
            int sq = (int)Math.sqrt(arr[i]);
 
            // Replace elements that are
            // not perfect squares with 0
            if (sq * sq != arr[i])
                arr[i] = 0;
        }
 
        // Build segment tree from the
        // given array
        int st[] = constructST(arr, n);
 
        // Iterate through all the queries
        for (int i = 0; i < q; i++) {
            int l = Query[i][0];
            int r = Query[i][1];
 
            // Print sum of values in
            // array from index l to r
            System.out.print(getSum(st, n, l, r) + " ");
        }
    }
 
    // Driver Code
    public static void main(String[] args)
    {
 
        int arr[] = { 2, 4, 5, 6, 9 };
        int N = arr.length;
        int Q = 3;
        int Query[][] = { { 0, 2 }, { 1, 3 }, { 1, 4 } };
        OddDivisorsSum(N, Q, arr, Query);
    }
}
 
// This code is contributed by Kingash.


Python3




import math
 
# Function to get the middle index
# from the given ranges
def get_mid(s, e):
    return s + math.floor((e - s) / 2)
 
# Recursive function to find the sum
# of values in the given range of
# the array
def get_sum_util(st, ss, se, qs, qe, si):
    # If segment of this node is a
    # part of given range, then
    # return the sum of the segment
    if qs <= ss and qe >= se:
        return st[si]
 
    # If segment of this node is
    # outside the given range
    if se < qs or ss > qe:
        return 0
 
    # If a part of this segment
    # overlaps the given range
    mid = get_mid(ss, se)
 
    return get_sum_util(st, ss, mid, qs, qe, 2 * si + 1) + \
           get_sum_util(st, mid + 1, se, qs, qe, 2 * si + 2)
 
# Function to find the sum of elements
# in the range from index qs (query
# start) to qe (query end)
def get_sum(st, n, qs, qe):
    # Invalid ranges
    if qs < 0 or qe > n - 1 or qs > qe:
        return -1
 
    return get_sum_util(st, 0, n - 1, qs, qe, 0)
 
# Recursive function to construct the
# Segment Tree for array[ss..se]. si
# is index of current node in tree st
def construct_st_util(arr, ss, se, st, si):
    # If there is one element
    # in the array
    if ss == se:
        st[si] = arr[ss]
        return arr[ss]
 
    mid = get_mid(ss, se)
 
    # Recur for left and right
    # subtrees and store the sum
    # of values in this node
    st[si] = construct_st_util(arr, ss, mid, st, si * 2 + 1) + \
             construct_st_util(arr, mid + 1, se, st, si * 2 + 2)
    return st[si]
 
# Function to construct segment tree
# from the given array
def construct_st(arr, n):
    # Allocate memory for the segment
    # tree Height of segment tree
    x = math.ceil(math.log(n) / math.log(2))
 
    # Maximum size of segment tree
    max_size = 2 * math.pow(2, x) - 1
 
    # Allocate memory
    st = [0] * int(max_size)
 
    # Fill the allocated memory st
    construct_st_util(arr, 0, n - 1, st, 0)
 
    # Return the constructed
    # segment tree
    return st
 
# Function to find the sum of elements
# having odd number of divisors in
# index range [L, R] for Q queries
def odd_divisors_sum(n, q, arr, Query):
    # Traverse the array,
    for i in range(n):
        sq = arr[i] ** 0.5
 
        # Replace elements that are
        # not perfect squares with 0
        if (sq * sq != arr[i]):
                arr[i] = 0;
         
    # Build segment tree from the
    # given array
    st = construct_st(arr, n);
  
    # Iterate through all the queries
    for i in range(q):
        l, r = Query[i][0], Query[i][1]
         
        # Print sum of values in
        # array from index l to r
        print(get_sum(st, n, l, r), end = " ");
    print()
         
# Driver Code
arr = [2, 4, 5, 6, 9];
N = len(arr);
Q = 3;
Query = [[ 0, 2 ], [ 1, 3 ], [ 1, 4 ]];
odd_divisors_sum(N, Q, arr, Query);
 
# This code is contributed by phasing17.


C#




// C# program for the above approach
 
using System;
using System.Linq;
using System.Collections.Generic;
 
public class GFG {
 
    // Function to get the middle index
    // from the given ranges
    static int getMid(int s, int e)
    {
        return s + (e - s) / 2;
    }
 
    // Recursive function to find the sum
    // of values in the given range of
    // the array
    static int getSumUtil(int[] st, int ss, int se, int qs,
                          int qe, int si)
    {
 
        // If segment of this node is a
        // part of given range, then
        // return the sum of the segment
        if (qs <= ss && qe >= se)
            return st[si];
 
        // If segment of this node is
        // outside the given range
        if (se < qs || ss > qe)
            return 0;
 
        // If a part of this segment
        // overlaps the given range
        int mid = getMid(ss, se);
 
        return getSumUtil(st, ss, mid, qs, qe, 2 * si + 1)
            + getSumUtil(st, mid + 1, se, qs, qe,
                         2 * si + 2);
    }
 
    // Function to find the sum of elements
    // in the range from index qs (query
    // start) to qe (query end)
    static int getSum(int[] st, int n, int qs, int qe)
    {
        // Invalid ranges
        if (qs < 0 || qe > n - 1 || qs > qe) {
            Console.WriteLine("Invalid Input");
            return -1;
        }
 
        return getSumUtil(st, 0, n - 1, qs, qe, 0);
    }
 
    // Recursive function to construct the
    // Segment Tree for array[ss..se]. si
    // is index of current node in tree st
    static int constructSTUtil(int[] arr, int ss, int se,
                               int[] st, int si)
    {
        // If there is one element
        // in the array
        if (ss == se) {
            st[si] = arr[ss];
            return arr[ss];
        }
 
        int mid = getMid(ss, se);
 
        // Recur for left and right
        // subtrees and store the sum
        // of values in this node
        st[si]
            = constructSTUtil(arr, ss, mid, st, si * 2 + 1)
              + constructSTUtil(arr, mid + 1, se, st,
                                si * 2 + 2);
        return st[si];
    }
 
    // Function to construct segment tree
    // from the given array
    static int[] constructST(int[] arr, int n)
    {
        // Allocate memory for the segment
        // tree Height of segment tree
        int x = (int)(Math.Ceiling(Math.Log(n) / Math.Log(2)));
 
        // Maximum size of segment tree
        int max_size = 2 * (int)Math.Pow(2, x) - 1;
 
        // Allocate memory
        int[] st = new int[max_size];
 
        // Fill the allocated memory st
        constructSTUtil(arr, 0, n - 1, st, 0);
 
        // Return the constructed
        // segment tree
        return st;
    }
 
    // Function to find the sum of elements
    // having odd number of divisors in
    // index range [L, R] for Q queries
    static void OddDivisorsSum(int n, int q, int[] arr,
                               int[][] Query)
    {
        // Traverse the array, arr[]
        for (int i = 0; i < n; i++) {
            int sq = (int)Math.Sqrt(arr[i]);
 
            // Replace elements that are
            // not perfect squares with 0
            if (sq * sq != arr[i])
                arr[i] = 0;
        }
 
        // Build segment tree from the
        // given array
        int[] st = constructST(arr, n);
 
        // Iterate through all the queries
        for (int i = 0; i < q; i++) {
            int l = Query[i][0];
            int r = Query[i][1];
 
            // Print sum of values in
            // array from index l to r
            Console.Write(getSum(st, n, l, r) + " ");
        }
    }
 
    // Driver Code
    public static void Main(string[] args)
    {
 
        int[] arr = { 2, 4, 5, 6, 9 };
        int N = arr.Length;
        int Q = 3;
        int[][] Query = { new int[] { 0, 2 }, new int[] { 1, 3 }, new int[] { 1, 4 } };
        OddDivisorsSum(N, Q, arr, Query);
    }
}
 
// This code is contributed by phasing17.


Javascript




<script>
 
// JavaScript program for the above approach
 
// Function to get the middle index
// from the given ranges
function getMid(s,e)
{
    return s + Math.floor((e - s) / 2);
}
 
// Recursive function to find the sum
// of values in the given range of
// the array
function getSumUtil(st,ss,se,qs,qe,si)
{
    // If segment of this node is a
        // part of given range, then
        // return the sum of the segment
        if (qs <= ss && qe >= se)
            return st[si];
  
        // If segment of this node is
        // outside the given range
        if (se < qs || ss > qe)
            return 0;
  
        // If a part of this segment
        // overlaps the given range
        let mid = getMid(ss, se);
  
        return getSumUtil(st, ss, mid, qs, qe, 2 * si + 1)
            + getSumUtil(st, mid + 1, se, qs, qe,
                         2 * si + 2);
    }
  
    // Function to find the sum of elements
    // in the range from index qs (query
    // start) to qe (query end)
    function getSum( st,  n,  qs,  qe)
    {
        // Invalid ranges
        if (qs < 0 || qe > n - 1 || qs > qe) {
            document.write("Invalid Input");
            return -1;
        }
  
        return getSumUtil(st, 0, n - 1, qs, qe, 0);
    }
 
// Recursive function to construct the
// Segment Tree for array[ss..se]. si
// is index of current node in tree st
function  constructSTUtil(arr,ss,se,st,si)
{
    // If there is one element
        // in the array
        if (ss == se) {
            st[si] = arr[ss];
            return arr[ss];
        }
  
        let mid = getMid(ss, se);
  
        // Recur for left and right
        // subtrees and store the sum
        // of values in this node
        st[si]
            = constructSTUtil(arr, ss, mid, st, si * 2 + 1)
              + constructSTUtil(arr, mid + 1, se, st,
                                si * 2 + 2);
        return st[si];
}
 
// Function to construct segment tree
    // from the given array
function constructST(arr,n)
{
    // Allocate memory for the segment
        // tree Height of segment tree
        let x = (Math.ceil(Math.log(n) / Math.log(2)));
  
        // Maximum size of segment tree
        let max_size = 2 * Math.pow(2, x) - 1;
  
        // Allocate memory
        let st = new Array(max_size);
  
        // Fill the allocated memory st
        constructSTUtil(arr, 0, n - 1, st, 0);
  
        // Return the constructed
        // segment tree
        return st;
}
 
// Function to find the sum of elements
    // having odd number of divisors in
    // index range [L, R] for Q queries
function OddDivisorsSum(n,q,arr,Query)
{
    // Traverse the array, arr[]
        for (let i = 0; i < n; i++) {
            let sq = Math.sqrt(arr[i]);
  
            // Replace elements that are
            // not perfect squares with 0
            if (sq * sq != arr[i])
                arr[i] = 0;
        }
  
        // Build segment tree from the
        // given array
        let st = constructST(arr, n);
  
        // Iterate through all the queries
        for (let i = 0; i < q; i++) {
            let l = Query[i][0];
            let r = Query[i][1];
  
            // Print sum of values in
            // array from index l to r
            document.write(getSum(st, n, l, r) + " ");
        }
}
 
 // Driver Code
let arr=[2, 4, 5, 6, 9];
let N = arr.length;
let Q = 3;
let Query=[[ 0, 2 ], [ 1, 3 ], [ 1, 4 ]];
OddDivisorsSum(N, Q, arr, Query);
 
 
 
// This code is contributed by avanitrachhadiya2155
 
</script>


Output: 

4 4 13

 

Time Complexity: O(Q * log(N))
Auxiliary Space: O(N)

Efficient Approach: To optimize the above approach, the idea is to use an auxiliary array that stores the prefix sum of elements having an odd number of divisors. Follow the steps below to solve the problem: 

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 elements
// having odd number of divisors in
// index range [L, R] for Q queries
void OddDivisorsSum(int n, int q, int a[],
                    vector<pair<int, int> > Query)
{
    // Initialize the dp[] array
    int DP[n] = { 0 };
 
    // Traverse the array, arr[]
    for (int i = 0; i < n; i++) {
        int x = sqrt(a[i]);
 
        // If a[i] is a perfect square,
        // then update value of DP[i] to a[i]
        if (x * x == a[i])
            DP[i] = a[i];
    }
 
    // Find the prefix sum of DP[] array
    for (int i = 1; i < n; i++) {
        DP[i] = DP[i - 1] + DP[i];
    }
 
    // Iterate through all the queries
    for (int i = 0; i < q; i++) {
 
        int l = Query[i].first;
        int r = Query[i].second;
 
        // Find the sum for each query
        if (l == 0) {
            cout << DP[r] << " ";
        }
        else {
            cout << DP[r] - DP[l - 1]
                 << " ";
        }
    }
}
 
// Driver Code
int main()
{
    int arr[] = { 2, 4, 5, 6, 9 };
    int N = sizeof(arr) / sizeof(arr[0]);
    int Q = 3;
    vector<pair<int, int> > Query
        = { { 0, 2 }, { 1, 3 }, { 1, 4 } };
    OddDivisorsSum(N, Q, arr, Query);
 
    return 0;
}


Java




/*package whatever //do not write package name here */
 
import java.io.*;
 
class GFG {
     
    // Function to find the sum of elements
    // having odd number of divisors in
    // index range [L, R] for Q queries
    static void OddDivisorsSum(int n, int q, int[] a,
                               int[][]  Query)
    {
        
        // Initialize the dp[] array
        int[] DP = new int[n];
  
        // Traverse the array, arr[]
        for (int i = 0; i < n; i++) {
            int x = (int)(Math.sqrt(a[i]));
  
            // If a[i] is a perfect square,
            // then update value of DP[i] to a[i]
            if (x * x == a[i])
                DP[i] = a[i];
        }
  
        // Find the prefix sum of DP[] array
        for (int i = 1; i < n; i++) {
            DP[i] = DP[i - 1] + DP[i];
        }
  
        // Iterate through all the queries
        for (int i = 0; i < q; i++) {
  
            int l = Query[i][0];
            int r = Query[i][1];
  
            // Find the sum for each query
            if (l == 0) {
                System.out.print(DP[r] + " ");
            }
            else {
                System.out.print(DP[r] - DP[l - 1] + " ");
            }
        }
    }
  
    // Driver Code
     
    public static void main (String[] args) {
         
        int[] arr = { 2, 4, 5, 6, 9 };
        int N = arr.length;
        int Q = 3;
        int[][] Query = { { 0, 2 }, { 1, 3 }, { 1, 4 } };
        OddDivisorsSum(N, Q, arr, Query);
         
         
    }
}


Python3




# Python3 program for the above approach
from math import sqrt
 
# Function to find the sum of elements
# having odd number of divisors in
# index range [L, R] for Q queries
def OddDivisorsSum(n, q, a, Query):
   
    # Initialize the dp[] array
    DP = [0]*n
     
    # Traverse the array, arr[]
    for i in range(n):
        x = sqrt(a[i])
 
        # If a[i] is a perfect square,
        # then update value of DP[i] to a[i]
        if (x * x == a[i]):
            DP[i] = a[i]
 
    # Find the prefix sum of DP[] array
    for i in range(1, n):
        DP[i] = DP[i - 1] + DP[i]
 
    # Iterate through all the queries
    for i in range(q):
        l = Query[i][0]
        r = Query[i][1]
 
        # Find the sum for each query
        if (l == 0):
            print(DP[r], end=" ")
        else:
            print(DP[r] - DP[l - 1], end=" ")
 
# Driver Code
if __name__ == '__main__':
    arr = [2, 4, 5, 6, 9]
    N = len(arr)
    Q = 3
    Query = [ [ 0, 2 ], [ 1, 3 ], [ 1, 4 ] ]
    OddDivisorsSum(N, Q, arr, Query)
 
    # 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 elements
    // having odd number of divisors in
    // index range [L, R] for Q queries
    static void OddDivisorsSum(int n, int q, int[] a,
                               int[, ] Query)
    {
       
        // Initialize the dp[] array
        int[] DP = new int[n];
 
        // Traverse the array, arr[]
        for (int i = 0; i < n; i++) {
            int x = (int)(Math.Sqrt(a[i]));
 
            // If a[i] is a perfect square,
            // then update value of DP[i] to a[i]
            if (x * x == a[i])
                DP[i] = a[i];
        }
 
        // Find the prefix sum of DP[] array
        for (int i = 1; i < n; i++) {
            DP[i] = DP[i - 1] + DP[i];
        }
 
        // Iterate through all the queries
        for (int i = 0; i < q; i++) {
 
            int l = Query[i, 0];
            int r = Query[i, 1];
 
            // Find the sum for each query
            if (l == 0) {
                Console.Write(DP[r] + " ");
            }
            else {
                Console.Write(DP[r] - DP[l - 1] + " ");
            }
        }
    }
 
    // Driver Code
    public static void Main()
    {
        int[] arr = { 2, 4, 5, 6, 9 };
        int N = arr.Length;
        int Q = 3;
        int[, ] Query = { { 0, 2 }, { 1, 3 }, { 1, 4 } };
        OddDivisorsSum(N, Q, arr, Query);
    }
}
 
// This code is contributed by ukasp.


Javascript




<script>
 
// Javascript program for the above approach
 
// Function to find the sum of elements
// having odd number of divisors in
// index range [L, R] for Q queries
function OddDivisorsSum(n, q, a, Query)
{
     
    // Initialize the dp[] array
    let DP = new Array(n);
     for(let i = 0; i < n; i++)
    {
        DP[i] = 0;
    }
     
    // Traverse the array, arr[]
    for(let i = 0; i < n; i++)
    {
        let x = Math.floor(Math.sqrt(a[i]));
 
        // If a[i] is a perfect square,
        // then update value of DP[i] to a[i]
        if (x * x == a[i])
            DP[i] = a[i];
    }
 
    // Find the prefix sum of DP[] array
    for(let i = 1; i < n; i++)
    {
        DP[i] = DP[i - 1] + DP[i];
    }
 
    // Iterate through all the queries
    for(let i = 0; i < q; i++)
    {
        let l = Query[i][0];
        let r = Query[i][1];
 
        // Find the sum for each query
        if (l == 0)
        {
            document.write(DP[r] + " ");
        }
        else
        {
            document.write(DP[r] - DP[l - 1] + " ");
        }
    }
}
 
// Driver Code
let arr = [ 2, 4, 5, 6, 9 ];
let N = arr.length;
let Q = 3
let Query = [ [ 0, 2 ],
              [ 1, 3 ],
              [ 1, 4 ] ];
               
OddDivisorsSum(N, Q, arr, Query);
 
// This code is contributed by patel2127
 
</script>


Output: 

4 4 13

 

Time complexity: O(N+Q)
Auxiliary Space: O(N)



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

Similar Reads