概念
定义域为正整数的函数是数论函数。
设p,q互质,f[p*q]=f[p]*f[q],称f为积性函数。如约数,欧拉,莫比乌斯。
任意p,q,f[p*q]=f[p]*f[q],称f为完全积性函数。如1函数,即f[i]=1。
我们一般用线性筛就可以预处理积性函数。
欧拉phi
void phii() { phi[1]=1; for(int i=2;i<=maxn;i++) { if(!not_prime[i]) { prime[++tot]=i; phi[i]=i-1; } for(int j=1;j<=tot&&prime[j]*i<=maxn;j++) { not_prime[i*prime[j]]=1; if(i%prime[j]==0) { phi[i*prime[j]]=phi[i]*prime[j]; break; } else phi[i*prime[j]]=phi[i]*phi[prime[j]]; } } }
莫比乌斯mu
void init() { notp[1]=1;mu[1]=1; for(int i=2;i<=maxn;++i) { if(!notp[i])prime[++tot]=i,mu[i]=-1; for(LL j=1;j<=tot&&i*prime[j]<=maxn;++j) { notp[i*prime[j]]=1; if(i%prime[j]==0) { mu[i*prime[j]]=0;//含有了平方因子 break; } else mu[i*prime[j]]=-mu[i];//质数个数++ } } }
约数
约数有两种,一种是求约数个数和,一种是求约数和
(不想自己手打原因)摘自这篇博客
打的时候不要把1给忘了
void init() { notp[1]=1;ys[1]=1;dd[1]=1; //ys约数个数,dd最小质因子的个数 for(re int i=2;i<=50000;++i) { if(!notp[i])prime[++tot]=i,ys[i]=2,dd[i]=1; for(re LL j=1;j<=tot&&i*prime[j]<=50000;++j) { notp[i*prime[j]]=1; if(i%prime[j]==0) { ys[i*prime[j]]=ys[i]/(dd[i]+1)*(dd[i]+2); dd[i*prime[j]]=dd[i]+1; break; } else { ys[i*prime[j]]=ys[i]*2;//(积性函数的性质,素数的约数个数=2) dd[i*prime[j]]=1;//prime[j]是i和i*prime[j]的最小素因子 } } } }
void init() { notp[1]=1;sd[1]=1;sp[1]=1; //sd约数和,sp最小质因子的那个多项式(也可以理解为由最小质因子组成的数的约数和吧) for(re int i=2;i<=50000;++i) { if(!notp[i])prime[++tot]=i,sd[i]=i+1,sp=i+1; for(re LL j=1;j<=tot&&i*prime[j]<=50000;++j) { notp[i*prime[j]]=1; if(i%prime[j]==0) { sd[i*prime[j]]=sd[i]/sp[i]*(sp[i]*prime[j]+1); sp[i*prime[j]]=sp[i]*prime[j]+1; break; } else { sd[i*prime[j]]=sd[i]*sd[prime[j]]; sp[i*prime[j]]=prime[j]+1; } } } }