给定四个整数m,n,a,b。找出从m到n的整数可以被a或b整除。
例子 :
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和除法。
- 用n除以a可以得到被’a’整除的所有数字(1到n)的总数。
- 将m-1除以a,即可得到可被“ a”整除的所有数字(1至m-1)的总数。
- 减去步骤1和2的计数即可获得m到n范围内的总除数。
现在,在给定范围内,总数为’a’的除数。重复上述操作以计算总除数“ b”。
将它们相加即可得出除数“ a”和“ b”的总数。
但是被a和b整除的数字计算了两次。因此,要消除这种歧义,我们可以使用a和b的LCM来计数被“ a”和“ b”整除的总数。
- 查找“ a”和“ b”的LCM。
- 将n除以LCM,即可得到可被“ a”和“ b”整除的数字(1到n)。
- 用LCM除以m-1以获得可被’a’和’b’整除的数字(1到m-1)。
- 减去第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)