定义
当然是用自己的话说:
对于欧拉函数((x)),写作(varphi(x)),读作(phispace x),而(varphi(x))表示:小于等于(x)的与(x)互质的正整数个数
注意:(1)与所有数互质
比如(varphi(1)=1)
怎么求?
1、(O(nlog(n))) 暴力
给定一个(n),我们暴力枚举小于等于(n)的正整数(i(1le ile n)),计算(gcd(i,n)),如果(gcd(n,i))等于(1),那么这两个数互质,(ans++)
2、(O(sqrt n)) 单独求
我们首先要把(sqrt n)内的质数筛出来,当然用(O(n))的欧拉筛,而不是(O(nloglog(n)))的埃筛(慢到炸裂)
void sieve(int x)
{
for(int i = 2;i <= x;++ i)
{
if(!vis[i])
prime[++pn] = i;
for(int j = 1;j <= pn && i * prime[j] <= x;++ j)
{
vis[prime[j] * i] = 1;
if(i % prime[j] == 0)
break;
}
}
}
根据公式:
[x=p_1^{b1}*p_2^{b2}*dots *p_n^{bn}
]
[varphi(x)=xprod_{i=1}^{n}(1-frac{1}{p_i})
]
单独求欧拉函数:
int getphi(int x)
{
int ret = x;
for(int i = 1;prime[i]*prime[i] <= x;++ i)
{
if(x % prime[i] == 0)
{
ret /= prime[i];
ret *= (prime[i]-1);
while(x % prime[i] == 0) x /= prime[i];
}
}
if(x != 1) ret /= x,ret *= (x-1);
return ret;
}
3、(O(n)) 线性筛
我们可以利用它是积性函数
求解
积性函数:在(gcd(x,y)=1)时,(f(x*y)=f(x)*f(y))
注意欧拉函数不是完全积性函数
完全积性函数:(f(x*y)=f(x)*f(y))
当(i)是质数的时候,(phi[i]=i-1)
当(ispace modspace p=0),(phi[p*i]=p*phi[i])
当(ispace modspace p e0),(phi[p*i]=phi[p]*phi[i])
void sieve(int x)
{
phi[1] = 1;
for(int i = 2;i <= x;++ i)
{
if(!vis[i])
{
prime[++pn] = i;
phi[i] = i-1;
}
for(int j = 1;j <= pn && i * prime[j] <= x;++ j)
{
vis[prime[j] * i] = 1;
if(i % prime[j] == 0)
{
phi[prime[j] * i] = prime[j] * phi[i];
break;
}
phi[prime[j] * i] = phi[prime[j]] * phi[i];
}
}
}