欧拉函数

定义

当然是用自己的话说:

对于欧拉函数((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];
		}
	}
}
原文地址:https://www.cnblogs.com/PPLPPL/p/13392311.html