[数论]欧拉函数

定义
在数论,对正整数n,欧拉函数是小于n的正整数中与n互质的数的数目,\(\varphi(1)=1\)
计算
两种计算方式
\ 1.直接计算
\ \(\varphi(x)=x \prod\limits_{i=1}^n(1-\frac{1}{p_i})\),其中\(p_1,p_2,\dots,p_n\)为x的所有质因数,\(x\)是不为\(0\)的整数

引用@Chhokmah的证明
以下的除法指整除。
\(\varphi(x)\)是欧拉函数,表示的是\([1,x]\)中和\(x\)互质的数的个数。
\(\varphi(x)=x\times \Pi_{p\in prime,p|x}(1-\frac 1p)\)
以上的证明:(用归纳证明)
\(p,q\in prime,p|x,q|x\),那么在\([1,x]\)中是\(p\)\(q\)的倍数的个数分别为\(\frac xp\)\(\frac xq\)
那么存在于\([1,x]\)中是\(p\)或者\(q\)的倍数的个数为\(\frac xp+\frac xq-\frac x{pq}\)。(这一步用到了容斥原理)
那么\(\varphi(x)\)也就是和\(p,q\)同时不互质的数的个数为\(x-\frac xp-\frac xq+\frac x{pq}\)
整一下上式得到\(x\times (1-\frac xp-\frac xq+\frac x{pq})=x\times (1-\frac 1p)\times(1-\frac 1q)\)
归纳一下就可以得到\(\varphi\)的推导式了。
对于上式推导式,可以用暴力求,时间复杂度为\(O(\sqrt n)\)

\ 2.递推计算

for(int i = 1; i <= maxn; ++i)
    phi[i] = i;
for(int i = 2; i <= maxn; i += 2)
    phi[i] >>= 1;
for(int i = 3; i <= maxn; i += 2)
    if(phi[i] == i)
        for(int j = i; j <= maxn; j += i)
            phi[j] = phi[j] / i * (i - 1);

\ UPD:欧拉筛的做法

int phi[20000005];
int primes[20000005], pcnt;
bool isnp[20000005];

void getPhi(int num){
    phi[1] = 1;
    for (int i = 2; i <= num; ++i){
        if (!isnp[i]) primes[++pcnt] = i, phi[i] = i - 1;
        for (int j = 1; j <= pcnt && i * primes[j] <= num; ++j){
            isnp[i * primes[j]] = 1;
            if (!(i % primes[j])){phi[i * primes[j]] = phi[i] * primes[j]; break;}
            phi[i * primes[j]] = phi[i] * (primes[j] - 1);
        }
    }
}
posted @ 2019-05-20 19:31  LinZhengmin  阅读(466)  评论(0编辑  收藏  举报

Contact with me