欧拉函数  已经优化到o(n)

欧拉函数    ψ(x)=x*(1-1/pi)  pi为x的质数因子

特殊性质(图片内容就是图片后面的文字)

欧拉函数是积性函数——若m,n互质,   ψ(m*n)=ψ(m)*ψ(n);

当n为奇数时,                 ψ(2*n)=ψ(n);

若n为质数则                                                                 ψ(n)=n-1;

代码实现求欧拉函数  复杂度O(n*n)  (有优化会补上)

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxn=1000005;
bool prime[maxn];
int p[maxn];  // form 1 kaishi
int ou[maxn];
int cnt;  // fan wei lei zhi shu ge shu
void build_prime(int n)
{
    for(int i=2;i<=n;i++) prime[i]=1;
    for(int i=2;i<=n;i++)
    {
        if(prime[i]==1) p[++cnt]=i;
        for(int j=1;j<=cnt && i*p[j]<=n;j++)
        {
            prime[i*p[j]]=0;
            if(i%p[j]==0) break;
        }
    }
}
void build_oulahanshu(int n)
{
    for(int i=1;i<=n;i++)
    {
        int num=i;
        int k=1;
        for(int j=1;p[j]<=i && j<=cnt;j++)
        {
            if(i%p[j]==0) num*=(p[j]-1),k*=p[j];
        }
        ou[i]=num/k;
     //   cout<<"==="<<ou[i]<<endl;
    }
}
int32_t main()
{
     int n; cin>>n;
     build_prime(n); cout<<cnt<<endl;
     build_oulahanshu(n);
     while(n--)
     {
         int x; cin>>x;
         cout<<ou[x]<<endl;
     }
}

 O(n log n)

#include<bits/stdc++.h>
using namespace std;
#define Max 1000001
int euler[Max];
int main(){
     euler[1]=1;
     for(int i=2;i<Max;i++)
       euler[i]=i;
     for(int i=2;i<Max;i++)
        if(euler[i]==i)
           for(int j=i;j<Max;j+=i)
              euler[j]=euler[j]/i*(i-1);
     for(int i=1;i<=100;i++)
    {
        cout<<euler[i]<<"  ";
        if( (i+1)%10==0 )cout<<endl;
    }

}

o(n)

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e7+10;
int vis[maxn];
int prime[maxn];
int phi[maxn];
void euler(int n)
{
    memset(vis,0,sizeof(vis));
    int tot=0;
phi[1]=1;
for(int i=2;i<=n;i++) { if(vis[i]==0) { vis[i]=i; prime[++tot]=i; // su shu hai phi[i]=i-1; // su shu de xian chu li } for(int j=1;j<=tot && prime[j]*i<n;j++) { if(prime[j]>vis[i] ) { // 超出n的范围 或者 i有比prime[j]更小的质因子; break; } // prime[j]是i*prime[j]的最小质因子 vis[i*prime[j]]=prime[j]; // phi[i*prime[j]]=phi[i]*( i%prime[j]?prime[j]-1:prime[j]); if( i%prime[j]) phi[i*prime[j]]=phi[i]*(prime[j]-1); else phi[i*prime[j]]=phi[i]*prime[j]; } } } int main() { int n=1e7+5; euler(n); cout<<phi[100000]<<endl; }
原文地址:https://www.cnblogs.com/Andromeda-Galaxy/p/9761113.html