忽然想写一篇有关欧拉函数的博客

关于欧拉函数:ios

定义:svg

φ(n)表示1~n中与n互质的数的个数;函数

求法:spa

已知n的标准分解式为:code

(哦对了,这里全部的因子都是质因子)blog

​那么
ci

而后求欧拉函数的两种方法:it

1.按照定义暴力求解:io

int phi(int n){
    int ret=n;
    for(int i=2;i*i<=n;i++){
        if(n%i==0){
            ret-=ret/i;
            while(n%i==0) n/=i;
        }
    }
    if(n>1) ret-=ret/n;
    return ret;
}

解释一下:class

对于欧拉函数φ来讲,咱们每*(1-1/pn),就至关于在原数的基础上减掉原数*1/pn(这里的原数并非指n,而是指n*某些数以后的数),假设原数为ret,那么咱们将ret*(1-1/pz)的值就至关于ret-ret*1/pz,由此咱们得出了ret-=ret/i;而后将n中的全部i通通除掉,防止出现再算一次的可凉(就是很凉)状况。最后,若是n>1,说明咱们还有一个因子没有枚举到,此时n就是当前因子,用上方式子再减一下就行了;

2.欧拉筛时顺带着求出来了???

而后欧拉筛的话,能够求到的值比较小,若是单纯求φ的话,不如用定义呢

#include<iostream>
#include<cstdlib>
#include<algorithm>
#include<ctime>

using namespace std;

int n,cnt,maxx;
int prime[10000010],phi[10000010];
bool not_[10000010];

void shai(){
    for(int i=2;i*i<=100000000;i++){
        if(!not_[i]) {
            prime[++cnt]=i;
            phi[i]=i-1;
        }
        for(int j=1;j<=cnt&&i*prime[j]<=n;j++){
            not_[i*prime[j]]=1;
            if(i%prime[j]==0) {
                phi[i*prime[j]]=phi[i]*prime[j];
                break;
            }
            else phi[i*prime[j]]=phi[i]*phi[prime[j]];
        }
    }
}

int main(){
    freopen("data.in","r",stdin);
    freopen("data.ans","w",stdout);
    cin>>n;
    shai();
    printf("%d",phi[n]);
}

end-

相关文章
相关标签/搜索