Count total divisors of A or B in a given range

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. 
 

  1. Divide n by a to obtain total count of all numbers(1 to n) divisible by β€˜a’. 
     
  2. Divide m-1 by a to obtain total count of all numbers(1 to m-1) divisible by β€˜a’. 
     
  3. 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’. 
 

  1. Find LCM of β€˜a’ and β€˜b’. 
     
  2. Divide n by LCM to obtain the count of numbers(1 to n) divisible by both β€˜a’ and β€˜b’. 
     
  3. Divide m-1 by LCM to obtain the count of numbers(1 to m-1) divisible by both β€˜a’ and β€˜b’. 
     
  4. 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++




// C++ program to count total divisors of 'a'
// or 'b' in a given range
#include <bits/stdc++.h>
using namespace std;
 
// Utility function to find LCM of two numbers
int FindLCM(int a, int b)
{
    return (a * b) / __gcd(a, b);
}
 
// Function to calculate all divisors in given range
int rangeDivisor(int m, int n, int a, int b)
{
    // Find LCM of a and b
    int lcm = FindLCM(a, b);
 
    int a_divisor = n / a - (m - 1) / a;
    int b_divisor = n / b - (m - 1) / b;
 
    // Find common divisor by using LCM
    int common_divisor = n / lcm - (m - 1) / lcm;
 
    int ans = a_divisor + b_divisor - common_divisor;
    return ans;
}
 
// Driver code
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




// Java program to count total divisors of 'a'
// or 'b' in a given range
 
import java.math.BigInteger;
 
class Test
{
    // Utility method to find LCM of two numbers
    static int FindLCM(int a, int b)
    {
        return (a * b) / new BigInteger(a+"").gcd(new BigInteger(b+"")).intValue();
    }
     
    // method to calculate all divisors in given range
    static int rangeDivisor(int m, int n, int a, int b)
    {
        // Find LCM of a and b
        int lcm = FindLCM(a, b);
      
        int a_divisor = n / a - (m - 1) / a;
        int b_divisor = n / b - (m - 1) / b;
      
        // Find common divisor by using LCM
        int common_divisor = n / lcm - (m - 1) / lcm;
      
        int ans = a_divisor + b_divisor - common_divisor;
        return ans;
    }
     
    // Driver method
    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




# python program to count total divisors
# of 'a' or 'b' in a given range
 
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
     
# Utility function to find LCM of two
# numbers
def FindLCM(a, b):
    return (a * b) / __gcd(a, b);
 
 
# Function to calculate all divisors in
# given range
def rangeDivisor(m, n, a, b):
     
    # Find LCM of a and b
    lcm = FindLCM(a, b)
 
    a_divisor = int( n / a - (m - 1) / a)
    b_divisor = int(n / b - (m - 1) / b)
     
    # Find common divisor by using LCM
    common_divisor =int( n / lcm - (m - 1) / lcm)
 
    ans = a_divisor + b_divisor - common_divisor
    return ans
 
# Driver code
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))
 
# This code is contributed by Sam007


C#




// C# program to count total divisors
// of 'a' or 'b' in a given range
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;
    }
     
    // Utility function to find LCM of
    // two numbers
    static int FindLCM(int a, int b)
    {
        return (a * b) / GCD(a, b);
    }
     
    // Function to calculate all divisors in given range
    static int rangeDivisor(int m, int n, int a, int b)
    {
        // Find LCM of a and b
        int lcm = FindLCM(a, b);
     
        int a_divisor = n / a - (m - 1) / a;
        int b_divisor = n / b - (m - 1) / b;
     
        // Find common divisor by using LCM
        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));
    }
}
 
// This code is contributed by Sam007.


PHP




<?php
// PHP program to count total
// divisors of 'a' or 'b' in
// a given range
 
function gcd($a, $b)
{
    return ($a % $b) ?
    gcd($b, $a % $b) :
                   $b;
}
 
 
// Utility function to
// find LCM of two numbers
function FindLCM($a, $b)
{
    return ($a * $b) / gcd($a, $b);
}
 
// Function to calculate
// all divisors in given range
function rangeDivisor($m, $n, $a, $b)
{
    // Find LCM of a and b
    $lcm = FindLCM($a, $b);
 
    $a_divisor = $n / $a - ($m - 1) / $a;
    $b_divisor = $n / $b - ($m - 1) / $b;
 
    // Find common divisor by using LCM
    $common_divisor = $n / $lcm -
                          ($m - 1) / $lcm;
 
    $ans = $a_divisor + $b_divisor -
                        $common_divisor;
    return $ans;
}
 
// Driver Code
$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)));
 
// This code is contributed by Sam007
?>


Javascript




<script>
 
    // JavaScript program to count total divisors
    // of 'a' or 'b' in a given range
     
    function GCD(num1, num2)
    {
        let Remainder;
   
        while (num2 != 0)
        {
            Remainder = num1 % num2;
            num1 = num2;
            num2 = Remainder;
        }
   
        return num1;
    }
       
    // Utility function to find LCM of
    // two numbers
    function FindLCM(a, b)
    {
        return parseInt((a * b) / GCD(a, b), 10);
    }
       
    // Function to calculate all divisors in given range
    function rangeDivisor(m, n, a, b)
    {
        // Find LCM of a and 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);
       
        // Find common divisor by using LCM
        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)