Count of elements having odd number of divisors in index range [L, R] for Q queries
Last Updated :
16 Oct, 2023
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 an 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 elements in the range [L, R] having odd numbers of divisors. If yes then count that element for that query.
Below is the implementation of the above approach:
C++14
#include <bits/stdc++.h>
using namespace std;
int OddDivisorsCount( int arr[], int N, int L, int R)
{
int count = 0;
for ( int i = L; i <= R; i++) {
int divisors = 0;
for ( int j = 1; j <= sqrt (arr[i]); j++) {
if (arr[i] % j == 0) {
if (arr[i] / j == j) {
divisors++;
}
else {
divisors += 2;
}
}
}
if (divisors % 2 != 0) {
count++;
}
}
return count;
}
int main()
{
int N = 5;
int Q = 3;
int arr[] = { 2, 4, 5, 6, 9 };
vector<pair< int , int > > Query
= { { 0, 2 }, { 1, 3 }, { 1, 4 } };
for ( int i = 0; i < Q; i++) {
int L = Query[i].first;
int R = Query[i].second;
cout << OddDivisorsCount(arr, N, L, R) << endl;
}
return 0;
}
|
Java
import java.util.*;
class Pair<A, B> {
A first;
B second;
public Pair(A first, B second) {
this .first = first;
this .second = second;
}
public A getFirst() {
return first;
}
public B getSecond() {
return second;
}
}
public class Main {
static int oddDivisorsCount( int [] arr, int N, int L, int R) {
int count = 0 ;
for ( int i = L; i <= R; i++) {
int divisors = 0 ;
for ( int j = 1 ; j <= Math.sqrt(arr[i]); j++) {
if (arr[i] % j == 0 ) {
if (arr[i] / j == j) {
divisors++;
} else {
divisors += 2 ;
}
}
}
if (divisors % 2 != 0 ) {
count++;
}
}
return count;
}
public static void main(String[] args) {
int N = 5 ;
int Q = 3 ;
int [] arr = { 2 , 4 , 5 , 6 , 9 };
List<Pair<Integer, Integer>> Query = new ArrayList<>();
Query.add( new Pair<>( 0 , 2 ));
Query.add( new Pair<>( 1 , 3 ));
Query.add( new Pair<>( 1 , 4 ));
for ( int i = 0 ; i < Q; i++) {
int L = Query.get(i).getFirst();
int R = Query.get(i).getSecond();
System.out.println(oddDivisorsCount(arr, N, L, R));
}
}
}
|
Python3
import math
def OddDivisorsCount(arr, N, L, R):
count = 0
for i in range (L, R + 1 ):
divisors = 0
for j in range ( 1 , int (math.sqrt(arr[i])) + 1 ):
if arr[i] % j = = 0 :
if arr[i] / / j = = j:
divisors + = 1
else :
divisors + = 2
if divisors % 2 ! = 0 :
count + = 1
return count
if __name__ = = "__main__" :
N = 5
Q = 3
arr = [ 2 , 4 , 5 , 6 , 9 ]
Query = [( 0 , 2 ), ( 1 , 3 ), ( 1 , 4 )]
for i in range (Q):
L = Query[i][ 0 ]
R = Query[i][ 1 ]
print (OddDivisorsCount(arr, N, L, R))
|
C#
using System;
using System.Collections.Generic;
class Program
{
static int OddDivisorsCount( int [] arr, int N, int L, int R)
{
int count = 0;
for ( int i = L; i <= R; i++)
{
int divisors = 0;
for ( int j = 1; j * j <= arr[i]; j++)
{
if (arr[i] % j == 0)
{
if (arr[i] / j == j)
{
divisors++;
}
else
{
divisors += 2;
}
}
}
if (divisors % 2 != 0)
{
count++;
}
}
return count;
}
static void Main()
{
int N = 5;
int Q = 3;
int [] arr = { 2, 4, 5, 6, 9 };
List<Tuple< int , int >> Query = new List<Tuple< int , int >>
{
new Tuple< int , int >(0, 2),
new Tuple< int , int >(1, 3),
new Tuple< int , int >(1, 4)
};
for ( int i = 0; i < Q; i++)
{
int L = Query[i].Item1;
int R = Query[i].Item2;
Console.WriteLine(OddDivisorsCount(arr, N, L, R));
}
}
}
|
Javascript
function OddDivisorsCount(arr, L, R) {
let count = 0;
for (let i = L; i <= R; i++) {
let divisors = 0;
for (let j = 1; j <= Math.sqrt(arr[i]); j++) {
if (arr[i] % j === 0) {
if (arr[i] / j === j) {
divisors++;
} else {
divisors += 2;
}
}
}
if (divisors % 2 !== 0) {
count++;
}
}
return count;
}
const N = 5;
const Q = 3;
const arr = [2, 4, 5, 6, 9];
const Query = [
[0, 2],
[1, 3],
[1, 4]
];
for (let i = 0; i < Q; i++) {
const L = Query[i][0];
const R = Query[i][1];
console.log(OddDivisorsCount(arr, L, R));
}
|
Output:
1
1
2
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:
- Initialize the array dp[] of size N with value 0.
- 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.
- To calculate the answer for each query efficiently we will precompute the answer.
- 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++
#include <bits/stdc++.h>
using namespace std;
void OddDivisorsCount(
int n, int q, int a[],
vector<pair< int , int > > Query)
{
int DP[n] = { 0 };
for ( int i = 0; i < n; i++) {
int x = sqrt (a[i]);
if (x * x == a[i])
DP[i] = 1;
}
for ( int i = 1; i < n; i++) {
DP[i] = DP[i - 1] + DP[i];
}
int l, r;
for ( int i = 0; i < q; i++) {
l = Query[i].first;
r = Query[i].second;
if (l == 0) {
cout << DP[r] << endl;
}
else {
cout << DP[r] - DP[l - 1]
<< endl;
}
}
}
int main()
{
int N = 5;
int Q = 3;
int arr[] = { 2, 4, 5, 6, 9 };
vector<pair< int , int > > Query
= { { 0, 2 }, { 1, 3 }, { 1, 4 } };
OddDivisorsCount(N, Q, arr, Query);
return 0;
}
|
Java
import java.util.*;
class GFG{
static class pair
{
int first, second;
public pair( int first, int second)
{
this .first = first;
this .second = second;
}
}
static void OddDivisorsCount( int n, int q,
int a[],
pair []Query)
{
int DP[] = new int [n];
for ( int i = 0 ; i < n; i++)
{
int x = ( int )Math.sqrt(a[i]);
if (x * x == a[i])
DP[i] = 1 ;
}
for ( int i = 1 ; i < n; i++)
{
DP[i] = DP[i - 1 ] + DP[i];
}
int l, r;
for ( int i = 0 ; i < q; i++)
{
l = Query[i].first;
r = Query[i].second;
if (l == 0 )
{
System.out.print(DP[r] + "\n" );
}
else
{
System.out.print(DP[r] -
DP[l - 1 ] + "\n" );
}
}
}
public static void main(String[] args)
{
int N = 5 ;
int Q = 3 ;
int arr[] = { 2 , 4 , 5 , 6 , 9 };
pair []Query = { new pair( 0 , 2 ),
new pair( 1 , 3 ),
new pair( 1 , 4 ) };
OddDivisorsCount(N, Q, arr, Query);
}
}
|
Python3
import math
def OddDivisorsCount(n, q, a, Query):
DP = [ 0 for i in range (n)]
for i in range (n):
x = int (math.sqrt(a[i]));
if (x * x = = a[i]):
DP[i] = 1 ;
for i in range ( 1 , n):
DP[i] = DP[i - 1 ] + DP[i];
l = 0
r = 0
for i in range (q):
l = Query[i][ 0 ];
r = Query[i][ 1 ];
if (l = = 0 ):
print (DP[r])
else :
print (DP[r] - DP[l - 1 ])
if __name__ = = "__main__" :
N = 5 ;
Q = 3 ;
arr = [ 2 , 4 , 5 , 6 , 9 ]
Query = [ [ 0 , 2 ],
[ 1 , 3 ],
[ 1 , 4 ] ]
OddDivisorsCount(N, Q, arr, Query);
|
C#
using System;
class GFG{
class pair
{
public int first, second;
public pair( int first, int second)
{
this .first = first;
this .second = second;
}
}
static void OddDivisorsCount( int n, int q,
int []a,
pair []Query)
{
int []DP = new int [n];
for ( int i = 0; i < n; i++)
{
int x = ( int )Math.Sqrt(a[i]);
if (x * x == a[i])
DP[i] = 1;
}
for ( int i = 1; i < n; i++)
{
DP[i] = DP[i - 1] + DP[i];
}
int l, r;
for ( int i = 0; i < q; i++)
{
l = Query[i].first;
r = Query[i].second;
if (l == 0)
{
Console.Write(DP[r] + "\n" );
}
else
{
Console.Write(DP[r] -
DP[l - 1] + "\n" );
}
}
}
public static void Main(String[] args)
{
int N = 5;
int Q = 3;
int []arr = { 2, 4, 5, 6, 9 };
pair []Query = { new pair(0, 2),
new pair(1, 3),
new pair(1, 4) };
OddDivisorsCount(N, Q, arr, Query);
}
}
|
Javascript
<script>
function OddDivisorsCount(
n, q, a,Query)
{
var DP = new Array(n).fill(0);
for ( var i = 0; i < n; i++) {
var x = Math.sqrt(a[i]);
if (x * x == a[i])
DP[i] = 1;
}
for ( var i = 1; i < n; i++) {
DP[i] = DP[i - 1] + DP[i];
}
var l, r;
for ( var i = 0; i < q; i++) {
l = Query[i][0];
r = Query[i][1];
if (l == 0) {
document.write( DP[r] + "<br>" );
}
else {
document.write( DP[r] - DP[l - 1]+ "<br>" );
}
}
}
var N = 5;
var Q = 3;
var arr = [2, 4, 5, 6, 9];
var Query
= [[0, 2 ], [1, 3 ], [1, 4 ]];
OddDivisorsCount(N, Q, arr, Query);
</script>
|
Time complexity:
- Precomputation: O(N)
- For each query: O(1)
Auxiliary Space: O(n)
Share your thoughts in the comments
Please Login to comment...