欧拉函数(模板)

欧拉函数求个数

时间复杂度 O(sqrt(n))

ll eular(ll n){
    ll ret=1,i;
    for (i=2;i*i<=n;i++)
        if (n%i==0){
            n/=i,ret*=i-1;
            while (n%i==0)
                n/=i,ret*=i;
        }
    if (n>1)
        ret*=n-1;
    return ret;
}
View Code

筛欧拉函数 + 素数

时间复杂度 O(n)

//欧拉线性筛:在线性时间内筛素数的同时求出所有数的欧拉函数
int tot;
int phi[MAXN];//保存各个数字的欧拉函数 
int prime[MAXN]; //按顺序保存素数
bool mark[MAXN];//判断是否是素数
void get_phi(){
    phi[1] = 1;
    for(int i = 2; i <= MAXN; i++){//相当于分解质因数的逆过程
        if(!mark[i]){
            prime[++tot] = i;
            phi[i] = i-1;
        }
        for(int j = 1; j <= tot; j++){
            if(i * prime[j] > N) break;
            mark[i * prime[j]] = 1;//确定i*prime[j]不是素数
            if(i % prime[j] == 0){//判断prime[j] 是否为 i的约数
                phi[i * prime[j]] = phi[i] * prime[j];
                break;
            }
            else{//prime[j] - 1 就是 phi[prime[j]],利用了欧拉函数的积性
                phi[i * prime[j]] = phi[i] * (prime[j] - 1);
            }
        }
    }
}
筛欧拉函数+素数

 欧拉函数的几个性质
1.对于质数p,φ(p)=p−1 φ(p)=p-1φ(p)=p−1。
2.若p为质数,n=pk n=p^kn=p
k
 ,则φ(n) φ(n)φ(n)=pk p^kp
k
 -pk−1 p^{k-1}p
k−1
 。
3.欧拉函数是积性函数,但不是完全积性函数。若m,n互质,则φ(m∗n)=φ(m)∗φ(n) φ(m*n)=φ(m)*φ(n)φ(m∗n)=φ(m)∗φ(n)。特殊的,当m=2,n为奇数时,φ(2*n)=φ(n)。
4.当n>2时,φ(n)是偶数。
5.小于n的数中,与n互质的数的总和为:φ(n) * n / 2 (n>1)。
6.n=∑d∣nφ(d) n=\sum_{d|n}{φ(d)}n=∑ d∣n​ φ(d),即n的因数(包括1和它自己)的欧拉函数之和等于n。

 

求欧拉函数另一个代码

埃拉托斯特尼筛求欧拉函数

这个复杂度虽然不是O(n),但还是挺快的(据说是O(n*ln ln n)

void euler(int n)
{
    for (int i=1;i<=n;i++) phi[i]=i;
    for (int i=2;i<=n;i++)
    {
        if (phi[i]==i)//这代表i是质数
        {
            for (int j=i;j<=n;j+=i)
            {
                phi[j]=phi[j]/i*(i-1);//把i的倍数更新掉
            }
        }
    }
}
View Code

 

上面来自原文:https://blog.csdn.net/liuzibujian/article/details/81086324

 

posted @ 2019-01-22 21:08  better46  阅读(620)  评论(0编辑  收藏  举报