给定数字N,通过选择从1到N的所有对,可以找到可以形成的所有GCD的总和。
例子:
Input : 4
Output : 7
Explanation:
Numbers from 1 to 4 are: 1, 2, 3, 4
Result = gcd(1,2) + gcd(1,3) + gcd(1,4) +
gcd(2,3) + gcd(2,4) + gcd(3,4)
= 1 + 1 + 1 + 1 + 2 + 1
= 7
Input : 12
Output : 105
Input : 1
Output : 0
Input : 2
Output : 1
天真的方法是在另一个内部运行两个循环。逐个选择所有对,找到每对的GCD,然后找到这些GCD的总和。该方法的时间复杂度为O(N 2 * log(N))
高效方法基于以下概念:
- 输入n的欧拉Totient函数?(n)是{1、2、3,…,n}中相对于n素数的数字的计数,即,n等于GCD(最大公约数)的数字为1。例如,?(4)= 2,?(3)= 2和?(5)=4。有2个小于或等于4的数字相对质数为4,2个小于或等于3的数字相对质数素数为3。小于或等于5的4个数相对于素数为5。
这个想法是将给定的问题转换为欧拉Totient函数之和。
Sum of all GCDs where j is a part of pair is and j is greater element in pair: Sumj = ?(i=1 to j-1) gcd(i, j) Our final result is Result = ?(j=1 to N) Sumj The above equation can be written as : Sumj = ? g * count(g) For every possible GCD 'g' of j. Here count(g) represents count of pairs having GCD equals to g. For every such pair(i, j), we can write : gcd(i/g, j/g) = 1 We can re-write our previous equation as Sumj = ? d * phi(j/d) For every divisor d of j and phi[] is Euler Totient number Example : j = 12 and d = 3 is one of divisor of j so in order to calculate the sum of count of all pairs having 3 as gcd we can simple write it as => 3*phi[12/3] => 3*phi[4] => 3*2 => 6 Therefore sum of GCDs of all pairs where 12 is greater part of pair and 3 is GCD. GCD(3, 12) + GCD(9, 12) = 6. Complete Example : N = 4 Sum1 = 0 Sum2 = 1 [GCD(1, 2)] Sum3 = 2 [GCD(1, 3) + GCD(2, 3)] Sum4 = 4 [GCD(1, 4) + GCD(3, 4) + GCD(2, 4)] Result = Sum1 + Sum2 + Sum3 + Sum4 = 0 + 1 + 2 + 4 = 7
以下是上述想法的实现。我们预先计算欧拉Totient函数,并计算所有数字的结果,直到达到最大值。在实现中使用的想法是基于这篇文章的。
C++
// C++ approach of finding sum of GCD of all pairs #include
using namespace std; #define MAX 100001 // phi[i] stores euler totient function for i // result[j] stores result for value j long long phi[MAX], result[MAX]; // Precomputation of phi[] numbers. Refer below link // for details : https://goo.gl/LUqdtY void computeTotient() { // Refer https://goo.gl/LUqdtY phi[1] = 1; for (int i=2; i
Java
// Java approach of finding // sum of GCD of all pairs. import java.lang.*; class GFG { static final int MAX = 100001; // phi[i] stores euler totient function for i // result[j] stores result for value j static long phi[] = new long[MAX]; static long result[] = new long[MAX]; // Precomputation of phi[] numbers. // Refer below link for details : // https://goo.gl/LUqdtY static void computeTotient() { // Refer https://goo.gl/LUqdtY phi[1] = 1; for (int i = 2; i < MAX; i++) { if (phi[i] == 0) { phi[i] = i - 1; for (int j = (i << 1); j < MAX; j += i) { if (phi[j] == 0) phi[j] = j; phi[j] = (phi[j] / i) * (i - 1); } } } } // Precomputes result for all // numbers till MAX static void sumOfGcdPairs() { // Precompute all phi value computeTotient(); for (int i = 1; i < MAX; ++i) { // Iterate throght all the // divisors of i. for (int j = 2; i * j < MAX; ++j) result[i * j] += i * phi[j]; } // Add summation of previous calculated sum for (int i = 2; i < MAX; i++) result[i] += result[i - 1]; } // Driver code public static void main(String[] args) { // Function to calculate sum of // all the GCD pairs sumOfGcdPairs(); int N = 4; System.out.println("Summation of " + N + " = " + result[N]); N = 12; System.out.println("Summation of " + N + " = " + result[N]); N = 5000; System.out.print("Summation of " + N + " = " + +result[N]); } } // This code is contributed by Anant Agarwal.
Python3
# Python approach of finding # sum of GCD of all pairs MAX = 100001 # phi[i] stores euler # totient function for # i result[j] stores # result for value j phi = [0] * MAX result = [0] * MAX # Precomputation of phi[] # numbers. Refer below link # for details : https://goo.gl/LUqdtY def computeTotient(): # Refer https://goo.gl/LUqdtY phi[1] = 1 for i in range(2, MAX): if not phi[i]: phi[i] = i - 1 for j in range(i << 1, MAX, i): if not phi[j]: phi[j] = j phi[j] = ((phi[j] // i) * (i - 1)) # Precomputes result # for all numbers # till MAX def sumOfGcdPairs(): # Precompute all phi value computeTotient() for i in range(MAX): # Iterate throght all # the divisors of i. for j in range(2, MAX): if i * j >= MAX: break result[i * j] += i * phi[j] # Add summation of # previous calculated sum for i in range(2, MAX): result[i] += result[i - 1] # Driver code # Function to calculate # sum of all the GCD pairs sumOfGcdPairs() N = 4 print("Summation of",N,"=",result[N]) N = 12 print("Summation of",N,"=",result[N]) N = 5000 print("Summation of",N,"=",result[N]) # This code is contributed # by Sanjit_Prasad.
C#
// C# approach of finding // sum of GCD of all pairs. using System; class GFG { static int MAX = 100001; // phi[i] stores euler totient // function for i result[j] // stores result for value j static long []phi = new long[MAX]; static long []result = new long[MAX]; // Precomputation of phi[] numbers. // Refer below link for details : // https://goo.gl/LUqdtY static void computeTotient() { // Refer https://goo.gl/LUqdtY phi[1] = 1; for (int i = 2; i < MAX; i++) { if (phi[i] == 0) { phi[i] = i - 1; for (int j = (i << 1); j < MAX; j += i) { if (phi[j] == 0) phi[j] = j; phi[j] = (phi[j] / i) * (i - 1); } } } } // Precomputes result for all // numbers till MAX static void sumOfGcdPairs() { // Precompute all phi value computeTotient(); for (int i = 1; i < MAX; ++i) { // Iterate throght all the // divisors of i. for (int j = 2; i * j < MAX; ++j) result[i * j] += i * phi[j]; } // Add summation of previous // calculated sum for (int i = 2; i < MAX; i++) result[i] += result[i - 1]; } // Driver code public static void Main() { // Function to calculate sum of // all the GCD pairs sumOfGcdPairs(); int N = 4; Console.WriteLine("Summation of " + N + " = " + result[N]); N = 12; Console.WriteLine("Summation of " + N + " = " + result[N]); N = 5000; Console.Write("Summation of " + N + " = " + +result[N]); } } // This code is contributed by Nitin Mittal.
PHP
输出:
Summation of 4 = 7 Summation of 12 = 105 Summation of 5000 = 61567426
时间复杂度: O(MAX * log(log MAX))
辅助空间: O(MAX)参考:
https://www.quora.com/How-can-I-solve-the-problem-GCD-Extreme-on-SPOJ-SPOJ-com-Problem-GCDEX