淺談線性篩能篩的函式
尤拉函式 \(φ(i)\)
尤拉函式是 \(1\sim n\) 的數中與 \(n\) 互質的個數,常寫成 phi
。
如何篩:
void init(){ phi[1]=1; for(int i=2;i<=n;i++){ if(!vis[i]){phi[i]=i-1;prime[++cnt]=i;} for(int j=1;j<=cnt&&i*prime[j]<=n;j++){ vis[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]]; } } }
對於 \(i\times prime\) 中只出現過一次最小質因子 \(prime\) 的情況(\(i\) 與 \(prime\) 互質),顯然對於 \(1\sim i\) 中每一個與 \(i\) 的數乘上 \(prime\) ,都可以產生一個與 \(i\times prime\) 互質的數;對於 \(i\times prime\) 出現過兩次及以上個 \(prime\) 的情況,就是要除掉 \(prime\) 與 \(i\times prime\) 這種情況(所以是 \(prime-1\))。
莫比烏斯函式 \(\mu(i)\)
我太菜了,不知道這個函式的性質除了頹式子還有什麼用。
如何篩:
void get_mu(int n) { mu[1]=1; for(int i=2;i<=n;i++) { if(!vis[i]){prim[++cnt]=i;mu[i]=-1;} for(int j=1;j<=cnt&&prim[j]*i<=n;j++) { vis[prim[j]*i]=1; if(i%prim[j]==0)break; else mu[i*prim[j]]=-mu[i]; } } }
就這樣篩吧,就是根據百度百科上的性質來篩。
約數數和函式 \(\sigma(i)\)
字面意思,常寫成 sigma
(其實符號就是小寫的 sigma
)
如何篩:(遠古的程式碼,有點沙比)
#include<bits/stdc++.h>
#define N 1000005
using namespace std;
int n,s[N],e[N],tot,p[N],v[N];
//tot:質數個數,p[i]:第i個質數,v[i]:i是否是質數
//s[i]:i的約數和,e[i]:不能被i的最小質因子整除的約數和
int main() {
cin>>n;
for(int i=2; i<=n; i++) {
if(!v[i]) {//當i是質數時
p[++tot]=i;//把i存進p
s[tot]=1+i;//i的約數和等於1+自身
e[tot]=1;//不能被i的最小質因子(即i)整除的約數和等於1
}
for(int j=1; j<=tot&&i*p[j]<=n; j++) {//詳解見下文
v[i*p[j]]=1;
if(i%p[j]) {//如果i和p[j]互質
s[i*p[j]]=s[i]*(p[j]+1);
//↑s[i*p[j]]=s[i]*s[j];這種寫法應該也可以
e[i*p[j]]=s[i];
} else {
s[i*p[j]]=s[i]*p[j]+e[i];
e[i*p[j]]=e[i];
break;
}
}
}
int ans=0;
for(int i=1; i<=n; i++) {//統計答案
ans+=s[i];
}
cout<<ans;
return 0;
}
約數個數和函式
字面意思,然而我也不知道符號表示是什麼。
如何篩:
void init(){
f[1]=g[1]=1;
for(int i=2;i<=M;++i){
if(!vis[i]) pr[++pn]=i,f[i]=2,g[i]=1;
for(int j=1;j<=pn&&i*pr[j]<=M;++j){
vis[i*pr[j]]=1;
if(i%pr[j]==0){
g[i*pr[j]]=g[i]+1;
f[i*pr[j]]=f[i]/(g[i]+1)*(g[i*pr[j]]+1);
break;
}
else g[i*pr[j]]=1,f[i*pr[j]]=f[i]<<1;
}
}
}
我們對於一個數有唯一分解定理:\(p=p_1^{k_1}\times p_2^{k_2} ⋯ \times p_n^{k_n}\)
所以對於一個數的約數個數為:\(\prod (k_i+1)\) 表示每個分解出來的 \(p_i\) 選幾個,因為可以不選,所以 \(+1\)。
我們定義 \(f(i)\) 為 \(i\) 的約數個數和,\(g(i)\) 為 \(i\) 的最小質因子出現的次數(分解出來的對應的指數 \(k\))。
當然,可以證得 \(f(i)\) 是積性函式。
根據線性篩的流程,當 \(i\) 與 \(prime\) 互質時,\(g(i\times prime)=1\),因為新 \(i\times prime\) 中 \(prime\) 的指數為 \(1\),所以約數個數要在 \(f(i)\) 的基礎上乘上 \(g(prime)+1=2=f(prime)\),也印證了 \(f(i)\) 是積性函式?\(f(i\times prime)=f(i)\times 2=f(i)\times f(prime)\);
反之,\(g(i\times prime)=g(i)+1\),\(f(i\times prime)=[g(i\times prime)+1]\times \frac{f(i)}{g(i)+1}\),意思是先把 \(f(i)\) 中的關於 \(prime\) 的貢獻項除掉,得出除掉 \(prime\) 以外的其他質因子的貢獻,再乘上新的 \(prime\) 的貢獻。