📜  计算给定范围内的A或B的总除数

📅  最后修改于: 2021-05-05 02:55:55             🧑  作者: Mango

给定四个整数m,n,a,b。找出从m到n的整数可以被ab整除。

例子 :

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

天真的方法是从m到n循环运行,并对所有可被a或b整除的数字进行计数。这种方法的时间复杂度将是O(m – n),对于较大的m值肯定会超时。

一种有效的方法是使用简单的LCM和除法。

  1. n除以a可以得到被’a’整除的所有数字(1到n)的总数。
  2. m-1除以a,即可得到可被“ a”整除的所有数字(1至m-1)的总数。
  3. 减去步骤1和2的计数即可获得m到n范围内的总除数。

现在,在给定范围内,总数为’a’的除数。重复上述操作以计算总除数“ b”。
将它们相加即可得出除数“ a”和“ b”的总数。
但是被a和b整除的数字计算了两次。因此,要消除这种歧义,我们可以使用a和b的LCM来计数被“ a”和“ b”整除的总数。

  1. 查找“ a”和“ b”的LCM。
  2. n除以LCM,即可得到可被“ a”和“ b”整除的数字(1到n)。
  3. 用LCM除以m-1以获得可被’a’和’b’整除的数字(1到m-1)。
  4. 减去第2步和第3步的计数,即可得到“ a”和“ b”的总除数。

现在,从先前的计算结果中减去该结果,即可得出“ a”或“ b”的所有唯一除数的总数。

C++
// C++ program to count total divisors of 'a'
// or 'b' in a given range 
#include 
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


输出:

6
190475

时间复杂度: O(log(MAX(a,b))
辅助空间: O(1)