定义
欧拉函数
欧拉函数,记作φ(n),表示的是在[1, n]中与n互质的数的个数。
性质
对于一个数n,如果n是质数,显然有φ(n)=n-1。
对于任意两个互质的整数a和b(即gcd(a,b) = 1),有φ(ab) = φ(a)φ(b)。
φ(n) = n × ∏(1 - 1/p)(或φ(n) = n × ∏((p-1)/p)(p为n的所有质因数)。
求单个数的欧拉函数
int euler_phi(int n)
{
int result = n;
for (int i = 2; i * i <= n; i++)
if (n % i == 0)
{
result = result / i * (i - 1);
while (n % i == 0) n /= i;
}
if (n > 1)
result = result / n * (n - 1);
return ans;
}求多个数的欧拉函数
constexpr int N = 1000000;
vector<int> primes;
bitset<N> is_not_prime;
int phi[N] = {0,1};
void eular_phi()
{
for(int i=2;i<=N;i++)
{
if(!is_not_prime[i])
{
primes.push_back(i);//不是素数则添加到primes中
phi[i] = i - 1;//并计算欧拉函数值
}
for(const int& prime:primes)//筛出从i*2到i*最后一个素数的合数
{
if(i*prime>N)
break;//超出筛选范围就没有必要再筛了
is_not_prime[i*prime]=true;//标记(合数=最小质因数*另一个数)为非素数
if(i%prime==0)//若真则i=prime(最小质因数)*另一个数(大于等于prime)
{
phi[i*prime] = phi[i] * prime;
break;//接下来的Prime都比现在的prime大,
//若继续循环则接下来的合数为(i*Prime=另一个数*Prime*prime)
//此数应在I=另一个数*Prime时被I*prime标记而不是现在
}
phi[i * prime] = phi[i] * phi[prime];
}
}
}