给定一个整数N ,任务是找到所有数字的最大公因数的总和,其中N本身最多为N。
例子:
Input: N = 12
Output: 40
Explanation:
GCD of [1, 12] = 1, [2, 12] = 2, [3, 12] = 3, [4, 12] = 4, [5, 12] = 1, [6, 12] = 6, [7, 12] = 1, [8, 12] = 4, [9, 12] = 3, [10, 12] = 2, [11, 12] = 1, [12, 12] = 12. The sum is (1 + 2 + 3 + 4 + 1 + 6 + 1 + 4 + 3 + 2 + 1 + 12) = 40.
Input: N = 2
Output: 3
Explanation:
GCD of [1, 2] = 1, [2, 2] = 2 and their sum is 3.
天真的方法:一个简单的解决方案是遍历从1到N的所有数字,并用N本身找到它们的gcd并继续加它们。
时间复杂度: O(N * log N)
高效方法:
为了优化上述方法,我们需要观察GCD(i,N)给出N的除数之一。因此,除了运行从1到N的循环外,我们还可以检查N的每个除数,用GCD(i,N)等于该除数的个数是多少。
Illustration:
For example N = 12, its divisors are 1, 2, 3, 4, 6, 12.
Numbers in range [1, 12] whose GCD with 12 is:
- 1 are {1, 5, 7, 11}
- 2 are {2, 10}
- 3 are {3, 9}
- 4 are {4, 8}
- 6 is {6}
- 12 is {12}
So answer is; 1*4 + 2*2 + 3*2 + 4*2 + 6*1 + 12*1 = 40.
- 因此,我们必须使用GCD d查找从1到N的整数个数,其中d是N的除数。让我们考虑x 1 ,x 2 ,x 3 ,…。 x n是从1到N的不同整数,因此它们的GCD和N是d。
- 由于GCD(x i ,N)= d,则GCD(x i / d,N / d)= 1
- 因此,GCD的N为d的从1到N的整数计数为(N / d)的欧拉托函数。
下面是上述方法的实现:
C++
// C++ Program to find the Sum
// of GCD of all integers up to N
// with N itself
#include
using namespace std;
// Function to Find Sum of
// GCD of each numbers
int getCount(int d, int n)
{
int no = n / d;
int result = no;
// Consider all prime factors
// of no. and subtract their
// multiples from result
for (int p = 2; p * p <= no; ++p) {
// Check if p is a prime factor
if (no % p == 0) {
// If yes, then update no
// and result
while (no % p == 0)
no /= p;
result -= result / p;
}
}
// If no has a prime factor greater
// than sqrt(n) then at-most one such
// prime factor exists
if (no > 1)
result -= result / no;
// Return the result
return result;
}
// Finding GCD of pairs
int sumOfGCDofPairs(int n)
{
int res = 0;
for (int i = 1; i * i <= n; i++) {
if (n % i == 0) {
// Calculate the divisors
int d1 = i;
int d2 = n / i;
// Return count of numbers
// from 1 to N with GCD d with N
res += d1 * getCount(d1, n);
// Check if d1 and d2 are
// equal then skip this
if (d1 != d2)
res += d2 * getCount(d2, n);
}
}
return res;
}
// Driver code
int main()
{
int n = 12;
cout << sumOfGCDofPairs(n);
return 0;
}
Java
// Java program to find the Sum
// of GCD of all integers up to N
// with N itself
class GFG{
// Function to Find Sum of
// GCD of each numbers
static int getCount(int d, int n)
{
int no = n / d;
int result = no;
// Consider all prime factors
// of no. and subtract their
// multiples from result
for(int p = 2; p * p <= no; ++p)
{
// Check if p is a prime factor
if (no % p == 0)
{
// If yes, then update no
// and result
while (no % p == 0)
no /= p;
result -= result / p;
}
}
// If no has a prime factor greater
// than Math.sqrt(n) then at-most one such
// prime factor exists
if (no > 1)
result -= result / no;
// Return the result
return result;
}
// Finding GCD of pairs
static int sumOfGCDofPairs(int n)
{
int res = 0;
for(int i = 1; i * i <= n; i++)
{
if (n % i == 0)
{
// Calculate the divisors
int d1 = i;
int d2 = n / i;
// Return count of numbers
// from 1 to N with GCD d with N
res += d1 * getCount(d1, n);
// Check if d1 and d2 are
// equal then skip this
if (d1 != d2)
res += d2 * getCount(d2, n);
}
}
return res;
}
// Driver code
public static void main(String[] args)
{
int n = 12;
System.out.print(sumOfGCDofPairs(n));
}
}
// This code is contributed by Amit Katiyar
Python3
# Python3 program to find the sum
# of GCD of all integers up to N
# with N itself
# Function to Find Sum of
# GCD of each numbers
def getCount(d, n):
no = n // d;
result = no;
# Consider all prime factors
# of no. and subtract their
# multiples from result
for p in range(2, int(pow(no, 1 / 2)) + 1):
# Check if p is a prime factor
if (no % p == 0):
# If yes, then update no
# and result
while (no % p == 0):
no //= p;
result -= result // p;
# If no has a prime factor greater
# than Math.sqrt(n) then at-most one such
# prime factor exists
if (no > 1):
result -= result // no;
# Return the result
return result;
# Finding GCD of pairs
def sumOfGCDofPairs(n):
res = 0;
for i in range(1, int(pow(n, 1 / 2)) + 1):
if (n % i == 0):
# Calculate the divisors
d1 = i;
d2 = n // i;
# Return count of numbers
# from 1 to N with GCD d with N
res += d1 * getCount(d1, n);
# Check if d1 and d2 are
# equal then skip this
if (d1 != d2):
res += d2 * getCount(d2, n);
return res;
# Driver code
if __name__ == '__main__':
n = 12;
print(sumOfGCDofPairs(n));
# This code is contributed by Amit Katiyar
C#
// C# program to find the sum
// of GCD of all integers up to N
// with N itself
using System;
class GFG{
// Function to find sum of
// GCD of each numbers
static int getCount(int d, int n)
{
int no = n / d;
int result = no;
// Consider all prime factors
// of no. and subtract their
// multiples from result
for(int p = 2; p * p <= no; ++p)
{
// Check if p is a prime factor
if (no % p == 0)
{
// If yes, then update no
// and result
while (no % p == 0)
no /= p;
result -= result / p;
}
}
// If no has a prime factor greater
// than Math.Sqrt(n) then at-most
// one such prime factor exists
if (no > 1)
result -= result / no;
// Return the result
return result;
}
// Finding GCD of pairs
static int sumOfGCDofPairs(int n)
{
int res = 0;
for(int i = 1; i * i <= n; i++)
{
if (n % i == 0)
{
// Calculate the divisors
int d1 = i;
int d2 = n / i;
// Return count of numbers
// from 1 to N with GCD d with N
res += d1 * getCount(d1, n);
// Check if d1 and d2 are
// equal then skip this
if (d1 != d2)
res += d2 * getCount(d2, n);
}
}
return res;
}
// Driver code
public static void Main(String[] args)
{
int n = 12;
Console.Write(sumOfGCDofPairs(n));
}
}
// This code is contributed by Amit Katiyar
40
时间复杂度: O(N)