欧拉函数
定义
当然是用自己的话说:
对于欧拉函数\((x)\),写作\(\varphi(x)\),读作\(phi\space x\),而\(\varphi(x)\)表示:小于等于\(x\)的与\(x\)互质的正整数个数
注意:\(1\)与所有数互质
比如\(\varphi(1)=1\)
怎么求?
1、\(O(nlog(n))\) 暴力
给定一个\(n\),我们暴力枚举小于等于\(n\)的正整数\(i(1\le i\le 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)=x\prod_{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\)
当\(i\space mod\space p=0\),\(phi[p*i]=p*phi[i]\)
当\(i\space mod\space p\ne0\),\(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];
}
}
}