欧拉函数

欧拉函数:<=n中与n互质数的个数

phi[1]=1,phi[2]=1;

1)单值:按题意暴力,

int euler(int n){
    int res=n;
    for(int i=2;i*i<=n;i++){//是i*i到n
        if(n%i==0){
            res=res/i*(i-1);
            while(n%i==0){
                n=n/i;
            }
        }
    }
    if(n>1) res=res/n*(n-1);//防止最终还有剩下因子
    return res;
} 

2)埃筛法:先用euler[i]数组内值代表初始状态(是否已被操作)

void init(){
    for(int i=2;i<=n;i++) phi[i]=i;
    for(int i=2;i<=n;i++)
       if(phi[i]==i){
              phi[i]=i-1;
              for(int j=2*i;j<=n;j+=i)
              phi[j]-=phi[j]/i;
       }
}

 3.线性筛法

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

性质:

1) 积性函数
      若m,n互质,
     特:当n为奇数时, 
2)n为质数  
 
 
e.g: UVA11426   
gcd(1,2)+gcd(1,3)+···+gcd(1,n)+gcd(2,3)+gcd(2,4)+ ···+gcd(2,n)+···+gcd(n-1,n)
 
利用性质:gcd(a,b)=p 等价于 gcd(a/p,b/p)=1;
将欧拉函数前缀和,同时注意将phi[1]=0(此时找到的都是小于本身的数),而欧拉函数是包括本身的。
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=4001000;
ll phi[N],n,ans;
void init(){
    for(int i=2;i<=n;i++) phi[i]=i;
    for(int i=2;i<=n;i++)
       if(phi[i]==i){
           phi[i]=i-1;
           for(int j=2*i;j<=n;j+=i)
           phi[j]-=phi[j]/i;
       }
    for(int i=1;i<=n;i++) phi[i]+=phi[i-1];
}
int main(){
    freopen("work.in","r",stdin);
    freopen("work.out","w",stdout);
    scanf("%lld",&n);init();
    for(int i=1;n/i>1;i++) ans+=i*phi[n/i];
    printf("%lld",ans);return 0;
}

 

posted @ 2018-08-20 19:47  ASDIC减除  阅读(166)  评论(0编辑  收藏  举报