【笔记】积性函数 与 欧拉函数

(PPT上有严谨的定义,下文还有清晰的证明
on 2020.1 by li'ao

摘自PPT:

积性函数


(其中 Def 是 定义 的意思
(注意,要互质才行!

欧拉函数


(其中 Def 表示 “定义”)

通项公式:


(其中p1, p2……pn为x的所有质因数,x是不为0的整数)
当p是素数时,

易由通项公式变形得来

现证通项公式

由积性函数的性质:
若(a,b)=1,则(phi(a*b) = phi(a) * phi(b))
对于(phi(n)),标准分解,(phi(n) = phi(p_1^{alpha_1} * p_2^{alpha_2} * p_3 ^ {alpha_3} * ... * p_k ^ {alpha_k})),
按照积性函数的性质,上式等于:

[phi(n) = phi(p_1^{alpha_1}) * phi(p_2^{alpha_2}) * phi(p_3 ^ {alpha_3}) * ... * phi(p_k ^ {alpha_k}) ]

以下证明(phi(p^alpha) = p^alpha - p^{alpha - 1})
因为p是质数,所以不与p互质的数都是p的倍数,在1~ (p^alpha) 中,(p) 的倍数有(p, 2 * p, 3 * p...(p ^ {alpha - 1}) * p)

(p ^ {alpha - 1} 个)

所以在1 ~ (p ^ alpha)中,共有 (p ^ alpha - p ^ {alpha - 1})个数与p互质,

所以在1 ~ (p ^ {alpha} - 1)中,也有 (p ^ alpha - p ^ {alpha - 1})个数与p互质

所以(phi(p ^ alpha) = p ^ alpha * ( 1 - frac{1}{p}))

易知(phi(n) = phi(p_1^{alpha_1}) * phi(p_2^{alpha_2}) * phi(p_3^{alpha_3}) * ... * phi(p_k^{alpha_k} ) = (p_1 ^ {alpha_1} * p_2 ^ {alpha_2} * ... *p_k ^ {alpha_k}) * (1 - frac{1}{p_1}) * (1 - frac{1}{p_2}) ... * (1 - frac{1}{p_k}))

得证。

线性求欧拉函数

性质

1.若p是素数,则(phi(p) = p - 1)

2.(对于质数p和任意正整数i)若(i,p) = 1, 则(phi(i * p) = phi(i) * (p - 1))

3.(对于质数p和任意正整数i)若i, p 不互质,则(phi(i * p) = phi(i) * p)

(1,2都易知的啦

第三条性质证明

若 n 和 i 不互质,则 (n + i ) 和 i 不互质....................................................1)

[1,i]中,与i不互质的数的个数为: (i - phi(i))

(由1)得)对于其中任意一个与i不互质的整数n, n + i 和 i 也不互质, 对于其中任意一个与i互质的数, 它加上i 还是与i 互质,所以:在[1 + i, i + i]中,与i不互质的数的个数还是

[i - phi(i) ]

对于一个素数p,前提条件,前提条件:i % p == 0,因为p是质数,所以i 是 p 的倍数(前提条件!

如此累加p个i,(其中p是素数),则在[1,p * i]中,与i 不互质的数的个数为

[p(i - phi(i)) = p * i - p * phi(i) ]

.....................................................................................................................2)
(稍微解释一下,就是对于任意k属于[0,p - 1],都有:在[1 + i * k, i + i * k]中与i不互质的数的个数为(i - phi(i)))

另一方面,[1, p * i]中与i * p不互质的数的个数为 (p * i - phi(p * i))..................3)

既然i是p的倍数,那么 2)式 等于 3)式
(解释一下:令i = p * k, i * p = k * p * p,
所以i 和 p * i 没有不同的因数
那么在[1, i * p]中,所有与k * p有公因数的数,必定也和 k * p * p 有公因数,即对于i 和 i * p, 在[1, i * p]中, 与他俩不互质的数的个数相等

[2) = 3) ]

[p * i - p * phi(i) = p * i - phi(p * i) ]

[phi(p * i) = p * phi(i) ]

得证。

代码实现

没错,就是根据3条性质来写代码

const int N = 300010;
int n, phi[N], pri[N], not_pri[N], top;

//这个函数是在线性欧拉素数筛的基础上写的,新加的东西只有 3行,(如果还不会线性素数筛,那就先看线性素数筛的模板 
void Phi(int n){
	not_pri[1] = 1;
	 
	F(i,2,n){
		if(!not_pri[i]){
			pri[++top] = i;
			phi[i] = i - 1;//QWQ1
			//i是素数,用到性质1 
		}	
		for(int j = 1; i * pri[j] <= n; j++){
			not_pri[i * pri[j]] = 1;
			if(i % pri[j]) phi[i * pri[j]] = phi[i] * (pri[j]- 1);//QWQ2
			//因为pri[j]是素数,所以如果i % pri[j] != 0, 即i 是 pri[j] 的倍数, 那么i 和 pri[j] 就互质,用性质2 
			else{
				phi[i * pri[j]] = phi[i] * pri[j];//QWQ3
				//如果i 和 pri[j]不互质,用到性质3 
				break;
			}
		}
	}
}
int main(){
	cin >> n;
	Phi(n);
	F(i,1,n)	cout << phi[i] << " ";
	return 0;
}

推送题目:洛谷P2158

原文地址:https://www.cnblogs.com/ZhengkunJia/p/12365003.html