欧拉函数o(n)求素数

Posted sun897949163

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了欧拉函数o(n)求素数相关的知识,希望对你有一定的参考价值。

欧拉函数的定义: E(N)= ( 区间[1,N-1] 中与 N 互质的整数个数).

  对于 积性函数 F(X*Y),当且仅当 GCD(X,Y)= 1 时, F(X*Y) = F(X)* F(Y)

  任意整数可因式分解为如下形式:技术分享

    其中( p1, p2 … pk 为质数, ei 为次数 ) 

  所以

    技术分享

  因为 欧拉函数 E(X)为积性函数, 所以

     技术分享

  对于 技术分享 , 我们知道 因为pi 为质数,所以 [ 1, pi-1 ] 区间的数都与 pi 互质

  对于 区间[ 1, 技术分享 ] ,共有 技术分享个数, 因为 技术分享 只有一个质因子,

  所以与 技术分享约数大于1 的必定包含 质因子 技术分享, 其数量为 技术分享
  

  所以    
技术分享
  又 E(N)为积性函数,所以可得 :

    技术分享

  又因为 技术分享其中( p1, p2 … pk 为质数, ei 为次数 ) 

     但是此计算公式,除法过多,所以计算速度较慢
技术分享

  在程序中利用欧拉函数如下性质,可以快速求出欧拉函数的值 ( P为N的质因子 )

    若(N%P==0 && (N/P)%P==0) 则有:E(N)=E(N/P)*P;

    若(N%P==0 && (N/P)%P!=0) 则有:E(N)=E(N/P)*(P-1);

//求[a, b]中 素数的个数
int prime[500];
int vis[500];
int phi[500];

void Prime(int n)
{
    int cnt = 0;
    memset(vis, 0, sizeof(vis));
    for (int i = 2; i<n; i++)
    {
        if (!vis[i])
        {
            prime[cnt++] = i;
            phi[i] = i - 1;
        }
        for (int j = 0; j<cnt&&i*prime[j]<n; j++)
        {
            __int64 k = i*prime[j];
            vis[k] = 1;
            if (i%prime[j] == 0)
            {
                phi[k] = phi[i] * prime[j];
                break;
            }
            else
                phi[k] = phi[i] * (prime[j] - 1);

        }
    }
}

int main (void)
{
    int a, b;
    while(scanf("%d %d", &a, &b) != EOF)
    {
        int ans = 0;
        for(int i = a; i <= b; i++)
        {
            ans += phi[i];
        }
        printf("%d\n", ans);
    }
    return 0;
}




以上是关于欧拉函数o(n)求素数的主要内容,如果未能解决你的问题,请参考以下文章

欧拉筛法求素数模版

欧拉筛法求素数

线性筛法(欧拉筛法)求素数

欧拉筛素数+求欧拉函数

欧拉线性筛 和 欧拉函数的求值

(转载)O(N)的素数筛选法和欧拉函数