欧拉函数

定义

当然是用自己的话说:

对于欧拉函数\((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];
		}
	}
}
posted @ 2020-07-28 17:20  皮皮刘  阅读(102)  评论(0编辑  收藏  举报