【模板】 素数、欧拉数、莫比乌斯函数小结

二话不说上代码:(如果有错误欢迎指出)

//By Menteur_Hxy
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;

int rd() {
    int x=0,fla=1; char c=' ';
    while(c>'9'|| c<'0') {if(c=='-') fla=-fla; c=getchar();}
    while(c<='9'&&c>='0') x=x*10+c-'0',c=getchar();
    return x*fla;
}

const int MAX=500010;
const int INF=0x3f3f3f3f;
int n;
int vis[MAX],p[MAX],phi[MAX],mu[MAX]; 

void getp1() { // 埃氏 
    int e=sqrt(n);
    for(int i=2;i<=e;++i)
        if(!vis[i])
            for(int j=i*i;j<=n;j+=i)
                vis[j]=1;
} 

void euler1() { //筛欧拉数 
    for(int i=1;i<=n;i++) phi[i]=i;
    for(int i=2;i<=n;i++) {
        if(phi[i]==i) 
            for(int j=i;j<=n;j+=i) //必须从i开始 
                phi[j]=phi[j]/i*(i-1);
    } 
}

void getp2() { //线性素数 
    int cnt=0;
    for(int i=2;i<=n;++i){
        if(!vis[i]) p[++cnt]=i;
        for(int j=1;j<=cnt && i*p[j]<=n;++j){
            vis[i*p[j]]=1;
            if(i%p[j]==0) break;
        }
    }
}

void euler2() { //线性欧拉数 
    int cnt=0;
    for(int i=2;i<=n;++i){
        if(!vis[i]) p[++cnt]=i,phi[i]=i-1;
        for(int j=1;j<=cnt && i*p[j]<=n;++j){
            vis[i*p[j]]=1;
            if(i%p[j]==0) {
                phi[i*p[j]]=phi[i]*p[j];
                break;
            }
            phi[i*p[j]]=phi[i]*(p[j]-1);
        }
    }
}

void Mobius() { //线性莫比乌斯函数 
    mu[1]=1; int cnt=0;
    for(int i=2;i<=n;i++) {
        if(!vis[i]) p[++cnt]=i,mu[i]=-1;
        for(int j=1;j<=cnt && i*p[j]<=n;j++) {
            vis[i*p[j]]=1;
            if(!i%p[j]) {
//              mu[i*p[j]]=0;
                break;
            }
            mu[i*p[j]]=-mu[i];
        }
    }
}

int main() {
    n=rd();
}

猜你喜欢

转载自blog.csdn.net/ye_xingyu/article/details/79940595