亚线性筛

杜教筛

int prime[maxn],cnt;
bool vis[maxn];
ll phi[maxn],mu[maxn];

void init(){
    phi[1]=mu[1]=1;
    for(int i=2;i<=maxn;i++){
        if(!vis[i]){
            prime[cnt++]=i;
            phi[i]=i-1;
            mu[i]=-1;
        }
        for(int j=0;j mp1;
tr1::unordered_map mp2;
ll calc_phi(int n){
    if(n<=maxn) return phi[n];
    if(mp1.count(n)) return mp1[n];
    ll ans=1LL*n*(n+1)/2;
    for(int l=2,r;l<=n;l=r+1){
        r=n/(n/l);
        ans-=(r-l+1)*calc_phi(n/l);
    }
    return mp1[n]=ans;
}

ll calc_mu(int n) {
    if (n<=maxn) return mu[n];
    if (mp2.count(n)) return mp2[n];
    ll ans=1;
    for(int l=2,r;l<=n;l=r+1){
        r=n/(n/l);
        ans-=(r-l+1)*calc_mu(n/l);
    }
    return mp2[n]=ans;
}

你可能感兴趣的:(模板,莫比乌斯反演)