线性筛总结

雨燕双飞 提交于 2019-12-22 21:54:46

线性筛

总体思想:筛某个合数时,总是这个数的最小质因数筛除它。

划重点 :因数个数d(n)d(n)、因数和s(n)s(n)、欧拉函数phi(n)phi(n)、莫比乌斯函数mu(n)mu(n)等均为nn的积性函数,能很好的利用“最小质因数”筛法性质。

一、筛质数

处理出1e81e8以内的素数用时1s1s左右,实测复杂度为O(n)O(n)带一个小常数。

1e71e7以内则0.1s0.1s左右。

const int maxn = 1e7+7;
const int maxp = 7e5+7;

bool vis[maxn];
int prime[maxp], tot;

void getPrime() {
    for(int i=2; i<maxn; ++i) {
        if(!vis[i]) prime[++tot]=i;
        for(int j=1; j<=tot&&i*prime[j]<maxn; ++j) {
            vis[i*prime[j]]=1;
            if(i%prime[j]==0) break;
        }
    }
}

二、因数个数

d数组:d函数
num数组:最小质因数个数

const int maxn = 1e6+7;

int d[maxn], num[maxn], vis[maxn], p[maxn], tot;

void getDiv() {
    d[1]=1;
    for(int i=2; i<maxn; ++i) {
        if(!vis[i]) p[++tot]=i, d[i]=2, num[i]=1;
        for(int j=1; j<=tot&&i*p[j]<maxn; ++j) {
            int k=i*p[j]; vis[k]=1;
            if(i%p[j]==0) {
                num[k]=num[i]+1;
                d[k]=d[i]/num[k]*(num[k]+1);
                break;
            }
            num[k]=1;
            d[k]=d[i]*2;
        }
    }
}

三、因数和

s数组:s函数(1e61e6的s在1e61e6左右,用intint即可)
g数组:最小质因数对应的:pe+11p1=1+p+p2++pe=1+p(1+p++pe1)\displaystyle \frac{p^{e+1}-1}{p-1}=1+p+p^2+\dots+p^e=1+p*(1+p+\dots+p^{e-1})

const int maxn = 1e6+7;

int s[maxn], g[maxn], vis[maxn], p[maxn], tot;

void getSum() {
    s[1]=g[1]=1;
    for(int i=2; i<maxn; ++i) {
        if(!vis[i]) p[++tot]=i, s[i]=i+1, g[i]=i+1;
        for(int j=1; j<=tot&&i*p[j]<maxn; ++j) {
            int k=i*p[j]; vis[k]=1;
            if(i%p[j]==0) {
                g[k]=g[i]*p[j]+1;
                s[k]=s[i]/g[i]*g[k];
                break;
            }
            g[k]=p[j]+1;
            s[k]=s[i]*g[k];
        }
    }
}

四、欧拉函数

phi数组:欧拉函数

const int maxn = 1e7+7;
const int maxp = 7e5+7;

int prime[maxp], phi[maxn], tot;
bool vis[maxn];

void getPhi() {
    phi[1]=1;
    for(int i=2; i<maxn; ++i) {
        if(!vis[i]) prime[++tot]=i, phi[i]=i-1;
        for(int j=1; j<=tot&&i*prime[j]<maxn; ++j) {
            vis[i*prime[j]]=1;
            if(i%prime[j]==0) { phi[i*prime[j]]=phi[i]*prime[j]; break; }
            phi[i*prime[j]]=phi[i]*phi[prime[j]];
        }
    }
}

五、莫比乌斯函数

mu数组:莫比乌斯函数

const int maxn = 1e7+7;
const int maxp = 7e5+7;

int prime[maxp], mu[maxn], tot;
bool vis[maxn];

void getMu() {
    mu[1]=1;
    for(int i=2; i<maxn; ++i) {
        if(!vis[i]) prime[++tot]=i, mu[i]=-1;
        for(int j=1; j<=tot&&i*prime[j]<maxn; ++j) {
            vis[i*prime[j]]=1;
            if(i%prime[j]==0) { mu[i*prime[j]]=0; break; }
            mu[i*prime[j]]=-mu[i];
        }
    }
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!