欧拉线性筛模板

来源:互联网 发布:js解析url中的参数 编辑:程序博客网 时间:2024/06/05 14:32

O(n)求欧拉函数φ(i):

inline void linear_shaker() {    bool vis[maxn];    memset(vis,false,sizeof(vis));    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]]=true;            if (i%prime[j]==0) {phi[i*prime[j]]=phi[i]*prime[j];break;}            else phi[i*prime[j]]=phi[i]*(prime[j]-1);        }    }}

O(n)求莫比乌斯函数μ(i)(及其前缀和):

int sum[maxn]={0},mu[maxn]={0,1},prime[maxn],num=0;inline void get_mu() {    memset(mu,INF,sizeof(mu)),mu[1]=1;    for (register int i=2;i<maxn;++i) {        if (mu[i]==INF)            prime[++num]=i,mu[i]=-1;        for (int j=1;j<=num&&i*prime[j]<maxn;++j) {            if (i%prime[j]==0) {mu[i*prime[j]]=0;break;}            else mu[i*prime[j]]=-mu[i];        }    }    for (register int i=1;i<maxn;++i) sum[i]=sum[i-1]+mu[i];}

O(n)求约数个数d(i)(及其前缀和):
t[i]表示i的最小质因数的指数。

inline void linear_shaker() {    memset(vis,0,sizeof(vis));    d[1]=1,t[1]=0;    for (register int i=2;i<MAXN;++i) {        if (!vis[i]) prime[++tot]=i,d[i]=2,t[i]=1;        for (int j=1;j<=tot&&i*prime[j]<MAXN;++j) {            vis[i*prime[j]]=true;            if (i%prime[j]==0) {                d[i*prime[j]]=d[i]/(t[i]+1)*(t[i]+2);                t[i*prime[j]]=t[i]+1;                break;            }            d[i*prime[j]]=d[i]<<1;            t[i*prime[j]]=1;        }    }    for (register int i=2;i<MAXN;++i) d[i]+=d[i-1];}

关于其余约数的相关问题后面再填坑。。。

原创粉丝点击