ÈulerŤotient˚F结(ETF)Φ(N),用于将输入n是数字的计数在{1,2,3,…,N}互质到n,即,其GCD的数字(最大公约数),其中n为1。
例子:
Φ(5) = 4
gcd(1, 5) is 1, gcd(2, 5) is 1,
gcd(3, 5) is 1 and gcd(4, 5) is 1
Φ(6) = 2
gcd(1, 6) is 1 and gcd(5, 6) is 1,
我们已经讨论了不同的计算Euler Totient函数的方法,这些方法适用于单个输入。在必须多次调用欧拉Totient函数(例如10 ^ 5次)的问题中,简单的解决方案将导致TLE(超过时间限制)。这个想法是使用Eratosthenes筛。
使用Eratosthenes筛子找出所有最大数达到最大限制(例如10 ^ 5)的质数。
为了计算Φ(n),我们执行以下操作。
- 将结果初始化为n。
- 遍历所有小于或等于n的平方根的素数(这与简单方法不同。这不是遍历所有小于或等于平方根的数,而是仅遍历素数)。令当前素数为p。我们检查p是否除以n,如果是,则通过重复将其除以n来从n中删除所有出现的p。我们还将结果减少n / p(许多数字的GCD不会与n一起为1)。
- 最后我们返回结果。
C++
// C++ program to efficiently compute values
// of euler totient function for multiple inputs.
#include
using namespace std;
#define ll long long
const int MAX = 100001;
// Stores prime numbers upto MAX - 1 values
vector p;
// Finds prime numbers upto MAX-1 and
// stores them in vector p
void sieve()
{
ll isPrime[MAX+1];
for (ll i = 2; i<= MAX; i++)
{
// if prime[i] is not marked before
if (isPrime[i] == 0)
{
// fill vector for every newly
// encountered prime
p.push_back(i);
// run this loop till square root of MAX,
// mark the index i * j as not prime
for (ll j = 2; i * j<= MAX; j++)
isPrime[i * j]= 1;
}
}
}
// function to find totient of n
ll phi(ll n)
{
ll res = n;
// this loop runs sqrt(n / ln(n)) times
for (ll i=0; p[i]*p[i] <= n; i++)
{
if (n % p[i]== 0)
{
// subtract multiples of p[i] from r
res -= (res / p[i]);
// Remove all occurrences of p[i] in n
while (n % p[i]== 0)
n /= p[i];
}
}
// when n has prime factor greater
// than sqrt(n)
if (n > 1)
res -= (res / n);
return res;
}
// Driver code
int main()
{
// preprocess all prime numbers upto 10 ^ 5
sieve();
cout << phi(11) << "\n";
cout << phi(21) << "\n";
cout << phi(31) << "\n";
cout << phi(41) << "\n";
cout << phi(51) << "\n";
cout << phi(61) << "\n";
cout << phi(91) << "\n";
cout << phi(101) << "\n";
return 0;
}
Java
// Java program to efficiently compute values
// of euler totient function for multiple inputs.
import java.util.*;
class GFG{
static int MAX = 100001;
// Stores prime numbers upto MAX - 1 values
static ArrayList p = new ArrayList();
// Finds prime numbers upto MAX-1 and
// stores them in vector p
static void sieve()
{
int[] isPrime=new int[MAX+1];
for (int i = 2; i<= MAX; i++)
{
// if prime[i] is not marked before
if (isPrime[i] == 0)
{
// fill vector for every newly
// encountered prime
p.add(i);
// run this loop till square root of MAX,
// mark the index i * j as not prime
for (int j = 2; i * j<= MAX; j++)
isPrime[i * j]= 1;
}
}
}
// function to find totient of n
static int phi(int n)
{
int res = n;
// this loop runs sqrt(n / ln(n)) times
for (int i=0; p.get(i)*p.get(i) <= n; i++)
{
if (n % p.get(i)== 0)
{
// subtract multiples of p[i] from r
res -= (res / p.get(i));
// Remove all occurrences of p[i] in n
while (n % p.get(i)== 0)
n /= p.get(i);
}
}
// when n has prime factor greater
// than sqrt(n)
if (n > 1)
res -= (res / n);
return res;
}
// Driver code
public static void main(String[] args)
{
// preprocess all prime numbers upto 10 ^ 5
sieve();
System.out.println(phi(11));
System.out.println(phi(21));
System.out.println(phi(31));
System.out.println(phi(41));
System.out.println(phi(51));
System.out.println(phi(61));
System.out.println(phi(91));
System.out.println(phi(101));
}
}
// this code is contributed by mits
Python3
# Python3 program to efficiently compute values
# of euler totient function for multiple inputs.
MAX = 100001;
# Stores prime numbers upto MAX - 1 values
p = [];
# Finds prime numbers upto MAX-1 and
# stores them in vector p
def sieve():
isPrime = [0] * (MAX + 1);
for i in range(2, MAX + 1):
# if prime[i] is not marked before
if (isPrime[i] == 0):
# fill vector for every newly
# encountered prime
p.append(i);
# run this loop till square root of MAX,
# mark the index i * j as not prime
j = 2;
while (i * j <= MAX):
isPrime[i * j]= 1;
j += 1;
# function to find totient of n
def phi(n):
res = n;
# this loop runs sqrt(n / ln(n)) times
i = 0;
while (p[i] * p[i] <= n):
if (n % p[i]== 0):
# subtract multiples of p[i] from r
res -= int(res / p[i]);
# Remove all occurrences of p[i] in n
while (n % p[i]== 0):
n = int(n / p[i]);
i += 1;
# when n has prime factor greater
# than sqrt(n)
if (n > 1):
res -= int(res / n);
return res;
# Driver code
# preprocess all prime numbers upto 10 ^ 5
sieve();
print(phi(11));
print(phi(21));
print(phi(31));
print(phi(41));
print(phi(51));
print(phi(61));
print(phi(91));
print(phi(101));
# This code is contributed by mits
C#
// C# program to efficiently compute values
// of euler totient function for multiple inputs.
using System;
using System.Collections;
class GFG{
static int MAX = 100001;
// Stores prime numbers upto MAX - 1 values
static ArrayList p = new ArrayList();
// Finds prime numbers upto MAX-1 and
// stores them in vector p
static void sieve()
{
int[] isPrime=new int[MAX+1];
for (int i = 2; i<= MAX; i++)
{
// if prime[i] is not marked before
if (isPrime[i] == 0)
{
// fill vector for every newly
// encountered prime
p.Add(i);
// run this loop till square root of MAX,
// mark the index i * j as not prime
for (int j = 2; i * j<= MAX; j++)
isPrime[i * j]= 1;
}
}
}
// function to find totient of n
static int phi(int n)
{
int res = n;
// this loop runs sqrt(n / ln(n)) times
for (int i=0; (int)p[i]*(int)p[i] <= n; i++)
{
if (n % (int)p[i]== 0)
{
// subtract multiples of p[i] from r
res -= (res / (int)p[i]);
// Remove all occurrences of p[i] in n
while (n % (int)p[i]== 0)
n /= (int)p[i];
}
}
// when n has prime factor greater
// than sqrt(n)
if (n > 1)
res -= (res / n);
return res;
}
// Driver code
static void Main()
{
// preprocess all prime numbers upto 10 ^ 5
sieve();
Console.WriteLine(phi(11));
Console.WriteLine(phi(21));
Console.WriteLine(phi(31));
Console.WriteLine(phi(41));
Console.WriteLine(phi(51));
Console.WriteLine(phi(61));
Console.WriteLine(phi(91));
Console.WriteLine(phi(101));
}
}
// this code is contributed by mits
PHP
1)
$res -= (int)($res / $n);
return $res;
}
// Driver code
// preprocess all prime numbers upto 10 ^ 5
sieve();
print(phi(11)."\n");
print(phi(21)."\n");
print(phi(31)."\n");
print(phi(41)."\n");
print(phi(51)."\n");
print(phi(61)."\n");
print(phi(91)."\n");
print(phi(101)."\n");
// this code is contributed by mits
?>
输出:
10
12
30
40
32
60
72
100