Count of elements having odd number of divisors in index range [L, R] for Q queries

Given an array arr[] of N positive integers and the number of queries Q, each query contains two numbers L and R. The task is to count the number of elements in the array having odd number of divisors from index L to R.

Examples:

Input: arr[] = [2, 4, 5, 6, 9], Q = 3, Query[][] = { {0, 2}, {1, 3}, {1, 4} }
Output: 1 1 2
Explanation:
1st query: in 2 4 5 only 4 has an odd number of divisors.
2nd query: in 4 5 6 only 4 has an odd number of divisors.
3rd query: in 4 5 6 9 only 4, 9 has an odd number of divisors.

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

Naive Approach: The naive approach is to iterate over the array from L to R for each query and count the element in the range [L, R] having odd numbers of divisors. If yes then count that element for that query.



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

Efficient Approach: We can observe that the number of divisors is odd only in case of perfect squares. Hence the best solution is to check if the given number is a perfect square or not in the range [L, R]. Below are the steps:

  1. Initialise the array dp[] of size N with value 0.
  2. Traverse the given array arr[] and if any element in the it is a perfect square the update the value at that index in dp[] as 1.
  3. To calculate the answer for each query efficiently we will precompute the answer.
  4. We will do the prefix sum of the array dp[] and for each query in the range [L, R] the answer will be given by:
    OddDivisorCount(L, R) = DP[R] - DP[L-1]
    

Below is the implementation of the above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
  
// Function count the number of elements
// having odd number of divisors
void OddDivisorsCount(
    int n, int q, int a[],
    vector<pair<int, int> > Query)
{
    // Initialise dp[] array
    int DP[n] = { 0 };
  
    // Precomputation
    for (int i = 0; i < n; i++) {
        int x = sqrt(a[i]);
  
        if (x * x == a[i])
            DP[i] = 1;
    }
  
    // Find the Prefix Sum
    for (int i = 1; i < n; i++) {
        DP[i] = DP[i - 1] + DP[i];
    }
  
    int l, r;
  
    // Iterate for each query
    for (int i = 0; i < q; i++) {
        l = Query[i].first;
        r = Query[i].second;
  
        // Find the answer for each query
        if (l == 0) {
            cout << DP[r] << endl;
        }
        else {
            cout << DP[r] - DP[l - 1]
                 << endl;
        }
    }
}
  
// Driver Code
int main()
{
    int N = 5;
    int Q = 3;
  
    // Given array arr[]
    int arr[] = { 2, 4, 5, 6, 9 };
  
    // Given Query
    vector<pair<int, int> > Query
        Query
        = { { 0, 2 }, { 1, 3 }, { 1, 4 } };
  
    // Function Call
    OddDivisorsCount(N, Q, arr, Query);
  
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program for the above approach
import java.util.*;
  
class GFG{
      
static class pair
    int first, second; 
    public pair(int first, int second) 
    
        this.first = first; 
        this.second = second; 
    
  
// Function count the number of elements
// having odd number of divisors
static void OddDivisorsCount(int n, int q,
                             int a[], 
                             pair []Query)
{
      
    // Initialise dp[] array
    int DP[] = new int[n];
  
    // Precomputation
    for(int i = 0; i < n; i++)
    {
       int x = (int)Math.sqrt(a[i]);
         
       if (x * x == a[i])
           DP[i] = 1;
    }
      
    // Find the Prefix Sum
    for(int i = 1; i < n; i++)
    {
       DP[i] = DP[i - 1] + DP[i];
    }
      
    int l, r;
  
    // Iterate for each query
    for(int i = 0; i < q; i++)
    {
       l = Query[i].first;
       r = Query[i].second;
         
       // Find the answer for each query
       if (l == 0)
       {
           System.out.print(DP[r] + "\n");
       }
       else
       {
           System.out.print(DP[r] - 
                            DP[l - 1] + "\n");
       }
    }
}
  
// Driver Code
public static void main(String[] args)
{
    int N = 5;
    int Q = 3;
  
    // Given array arr[]
    int arr[] = { 2, 4, 5, 6, 9 };
  
    // Given Query
    pair []Query = { new pair(0, 2),
                     new pair(1, 3), 
                     new pair(1, 4) };
  
    // Function Call
    OddDivisorsCount(N, Q, arr, Query);
}
}
  
// This code is contributed by amal kumar choubey

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# program for the above approach
using System;
  
class GFG{
class pair
    public int first, second; 
    public pair(int first, int second) 
    
        this.first = first; 
        this.second = second; 
    
  
// Function count the number of elements
// having odd number of divisors
static void OddDivisorsCount(int n, int q,
                             int []a, 
                             pair []Query)
{
      
    // Initialise []dp array
    int []DP = new int[n];
  
    // Precomputation
    for(int i = 0; i < n; i++)
    {
       int x = (int)Math.Sqrt(a[i]);
       if (x * x == a[i])
           DP[i] = 1;
    }
      
    // Find the Prefix Sum
    for(int i = 1; i < n; i++)
    {
       DP[i] = DP[i - 1] + DP[i];
    }
      
    int l, r;
  
    // Iterate for each query
    for(int i = 0; i < q; i++)
    {
       l = Query[i].first;
       r = Query[i].second;
         
       // Find the answer for each query
       if (l == 0)
       {
           Console.Write(DP[r] + "\n");
       }
       else
       {
           Console.Write(DP[r] - 
                         DP[l - 1] + "\n");
       }
    }
}
  
// Driver Code
public static void Main(String[] args)
{
    int N = 5;
    int Q = 3;
  
    // Given array []arr
    int []arr = { 2, 4, 5, 6, 9 };
  
    // Given Query
    pair []Query = { new pair(0, 2),
                     new pair(1, 3), 
                     new pair(1, 4) };
  
    // Function Call
    OddDivisorsCount(N, Q, arr, Query);
}
}
  
// This code is contributed by gauravrajput1

chevron_right


Output:

1
1
2

Time complexity:

  • Precomputation: O(N)
  • For each query: O(1)

Auxiliary Space: O(1)

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.




My Personal Notes arrow_drop_up

Recommended Posts:


Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.