Count total divisors of A or B in a given range
Last Updated :
21 May, 2021
Given four integers m, n, a, b. Find how many integers from range m to n are divisible by a or b.
Examples :
Input: 3 11 2 3
Output: 6
Explanation:
m = 3, n = 11, a = 2, b = 3
There are total 6 numbers from 3 to
11 which are divisible by 2 or 3 i.e,
3, 4, 6, 8, 9, 10
Input: arr[] = {11, 1000000, 6, 35}
Output: 190475
A Naive approach is to run a loop from m to n and count all numbers which are divisible by either a or b. Time complexity of this approach will be O(m – n) which will definitely time out for large values of m.
An efficient approach is to use simple LCM and division method.
- Divide n by a to obtain total count of all numbers(1 to n) divisible by ‘a’.
- Divide m-1 by a to obtain total count of all numbers(1 to m-1) divisible by ‘a’.
- Subtract the count of step 1 and 2 to obtain total divisors in range m to n.
Now we have a total number of divisors of ‘a’ in given range. Repeat the above to count total divisors of ‘b’.
Add these to obtain total count of divisors ‘a’ and ‘b’.
But the number divisible by both a and b counted twice. Therefore, to remove this ambiguity we can use LCM of a and b to count total number divisible by both ‘a’ and ‘b’.
- Find LCM of ‘a’ and ‘b’.
- Divide n by LCM to obtain the count of numbers(1 to n) divisible by both ‘a’ and ‘b’.
- Divide m-1 by LCM to obtain the count of numbers(1 to m-1) divisible by both ‘a’ and ‘b’.
- Subtract the count of steps 2 and 3 to obtain total divisors of both ‘a’ and ‘b’.
Now subtract this result from the previous calculated result to find total count of all unique divisors of ‘a’ or ‘b’.
C++
#include <bits/stdc++.h>
using namespace std;
int FindLCM( int a, int b)
{
return (a * b) / __gcd(a, b);
}
int rangeDivisor( int m, int n, int a, int b)
{
int lcm = FindLCM(a, b);
int a_divisor = n / a - (m - 1) / a;
int b_divisor = n / b - (m - 1) / b;
int common_divisor = n / lcm - (m - 1) / lcm;
int ans = a_divisor + b_divisor - common_divisor;
return ans;
}
int main()
{
int m = 3, n = 11, a = 2, b = 3;
cout << rangeDivisor(m, n, a, b) << endl;
m = 11, n = 1000000, a = 6, b = 35;
cout << rangeDivisor(m, n, a, b);
return 0;
}
|
Java
import java.math.BigInteger;
class Test
{
static int FindLCM( int a, int b)
{
return (a * b) / new BigInteger(a+ "" ).gcd( new BigInteger(b+ "" )).intValue();
}
static int rangeDivisor( int m, int n, int a, int b)
{
int lcm = FindLCM(a, b);
int a_divisor = n / a - (m - 1 ) / a;
int b_divisor = n / b - (m - 1 ) / b;
int common_divisor = n / lcm - (m - 1 ) / lcm;
int ans = a_divisor + b_divisor - common_divisor;
return ans;
}
public static void main(String args[])
{
int m = 3 , n = 11 , a = 2 , b = 3 ;
System.out.println(rangeDivisor(m, n, a, b));
m = 11 ; n = 1000000 ; a = 6 ; b = 35 ;
System.out.println(rangeDivisor(m, n, a, b));
}
}
|
Python3
def __gcd(x, y):
if x > y:
small = y
else :
small = x
for i in range ( 1 , small + 1 ):
if ((x % i = = 0 ) and (y % i = = 0 )):
gcd = i
return gcd
def FindLCM(a, b):
return (a * b) / __gcd(a, b);
def rangeDivisor(m, n, a, b):
lcm = FindLCM(a, b)
a_divisor = int ( n / a - (m - 1 ) / a)
b_divisor = int (n / b - (m - 1 ) / b)
common_divisor = int ( n / lcm - (m - 1 ) / lcm)
ans = a_divisor + b_divisor - common_divisor
return ans
m = 3
n = 11
a = 2
b = 3 ;
print (rangeDivisor(m, n, a, b))
m = 11
n = 1000000
a = 6
b = 35
print (rangeDivisor(m, n, a, b))
|
C#
using System;
class GFG {
static int GCD( int num1, int num2)
{
int Remainder;
while (num2 != 0)
{
Remainder = num1 % num2;
num1 = num2;
num2 = Remainder;
}
return num1;
}
static int FindLCM( int a, int b)
{
return (a * b) / GCD(a, b);
}
static int rangeDivisor( int m, int n, int a, int b)
{
int lcm = FindLCM(a, b);
int a_divisor = n / a - (m - 1) / a;
int b_divisor = n / b - (m - 1) / b;
int common_divisor = n / lcm - (m - 1) / lcm;
int ans = a_divisor + b_divisor - common_divisor;
return ans;
}
public static void Main ()
{
int m = 3, n = 11, a = 2, b = 3;
Console.WriteLine(rangeDivisor(m, n, a, b));
m = 11; n = 1000000;
a = 6; b = 35;
Console.WriteLine(rangeDivisor(m, n, a, b));
}
}
|
PHP
<?php
function gcd( $a , $b )
{
return ( $a % $b ) ?
gcd( $b , $a % $b ) :
$b ;
}
function FindLCM( $a , $b )
{
return ( $a * $b ) / gcd( $a , $b );
}
function rangeDivisor( $m , $n , $a , $b )
{
$lcm = FindLCM( $a , $b );
$a_divisor = $n / $a - ( $m - 1) / $a ;
$b_divisor = $n / $b - ( $m - 1) / $b ;
$common_divisor = $n / $lcm -
( $m - 1) / $lcm ;
$ans = $a_divisor + $b_divisor -
$common_divisor ;
return $ans ;
}
$m = 3;
$n = 11;
$a = 2;
$b = 3;
print ( ceil (rangeDivisor( $m , $n , $a , $b )));
echo "\n" ;
$m = 11;
$n = 1000000;
$a = 6;
$b = 35;
print ( ceil (rangeDivisor( $m , $n , $a , $b )));
?>
|
Javascript
<script>
function GCD(num1, num2)
{
let Remainder;
while (num2 != 0)
{
Remainder = num1 % num2;
num1 = num2;
num2 = Remainder;
}
return num1;
}
function FindLCM(a, b)
{
return parseInt((a * b) / GCD(a, b), 10);
}
function rangeDivisor(m, n, a, b)
{
let lcm = FindLCM(a, b);
let a_divisor = parseInt(n / a, 10) -
parseInt((m - 1) / a, 10);
let b_divisor = parseInt(n / b, 10) -
parseInt((m - 1) / b, 10);
let common_divisor = parseInt(n / lcm, 10) -
parseInt((m - 1) / lcm, 10);
let ans = a_divisor + b_divisor - common_divisor;
return ans;
}
let m = 3, n = 11, a = 2, b = 3;
document.write(rangeDivisor(m, n, a, b) + "</br>" );
m = 11; n = 1000000;
a = 6; b = 35;
document.write(rangeDivisor(m, n, a, b));
</script>
|
Output:
6
190475
Time complexity: O(log(MAX(a, b))
Auxiliary space: O(1)
Share your thoughts in the comments
Please Login to comment...