zoukankan      html  css  js  c++  java
  • 欧拉函数,打表求欧拉函数poj3090

    欧拉函数 φ(n) 定义:[1,N]中与N互质的数的个数

    //互质与欧拉函数
    
    /*
    求欧拉函数 
    按欧拉函数计算公式,只要分解质因数即可 
    */ 
    int phi(int n){
        int ans=n;
        for(int i=2;i<=sqrt(n);i++){
            if(n%i==0){
                ans=ans/i*(i-1);
                while(n%i==0) n/=i;
            }
        }
        if(n>1) ans=ans/n*(n-1);
        return ans;
    } 

    性质:1.[1,n]中与n互质的数的和为 n*φ(n)/2;

       2.欧拉函数是积性函数

         3.p|n && p*p|n =>φ(n)=φ(n/p)*p; 

         4.p|n && p*p不能整除n,则φ(n)=φ(n/p)*(p-1);

         5.sum{φ(d)}=n,d是n的约数

    打表求欧拉函数

    第一种是era筛的思路,O(nlogn)的复杂度,即每个质数p的倍数都乘以(1-1/p)即可

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    using namespace std;
    int phi[10000];
    void euler(int n){//用era筛的思路O(nlogn)复杂度 
        for(int i=2;i<=n;i++)phi[i]=i;
        for(int i=2;i<=n;i++)
            if(phi[i]==i)//i是质数
                for(int j=1;i*j<=n;j++)
                    phi[i*j]=phi[i*j]/i*(i-1); 
    }
    int main(){
        int t,n;
        euler(1000);
        scanf("%d",&t);
        for(int tt=1;tt<=t;tt++){
            scanf("%d",&n);
            int ans=0;
            for(int i=2;i<=n;i++)
                ans+=2*phi[i];
            printf("%d %d %d
    ",tt,n,ans+3);
        }
    } 

    第二种是线性筛的思路:复杂度O(n)

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    using namespace std;
    int phi[10000];
    int m,v[10000],prime[10000]; 
    void euler(int n){//用era筛的思路O(nlogn)复杂度 
        memset(v,0,sizeof v);
        m=0;
        for(int i=2;i<=n;i++){
            if(v[i]==0){//i是质数 
                v[i]=i,prime[++m]=i;
                phi[i]=i-1; 
            }
            for(int j=1;j<=m;j++){ 
                if(prime[j]>v[i] || prime[j]*i>n) break;
                v[i*prime[j]]=prime[j];
                phi[i*prime[j]]=phi[i]*(i%prime[j]?prime[j]-1://φ(n)=φ(n/p)*(p-1) 性质4
                                                    prime[j]);//φ(n)=φ(n/p)*p 性质3
            } 
        } 
    }
    int main(){
        int t,n;
        euler(1000);
        scanf("%d",&t);
        for(int tt=1;tt<=t;tt++){
            scanf("%d",&n);
            int ans=0;
            for(int i=2;i<=n;i++)
                ans+=2*phi[i];
            printf("%d %d %d
    ",tt,n,ans+3);
        }
    } 
  • 相关阅读:
    HDU 2045 不容易系列之(3)—— LELE的RPG难题 (递推)
    HDU 2050 折线分割平面 (递推)
    HDU 5441 Travel (并查集+数学+计数)
    HDU 4597 Play Game (DP,记忆化搜索,博弈)
    HDU 4599 Dice (概率DP+数学+快速幂)
    HDU 4497 GCD and LCM (数学,质数分解)
    UVa 1312 Cricket Field (枚举+离散化)
    HDU 4499 Cannon (暴力求解)
    HDU 4496 D-City (并查集)
    javascript你不知道的知识点
  • 原文地址:https://www.cnblogs.com/zsben991126/p/10233400.html
Copyright © 2011-2022 走看看