[總結] 線性篩與積性函式
[總結] 線性篩與積性函式
利用線性篩中一個數僅僅被它最小的質因子篩掉的性質,結合積性函式的特殊性質,往往可以預處理出積性函式的值。
\(\varphi(x)\)
設 \(P\) 是質數,顯然 \(\varphi(p)=p-1\)。
根據定義式:\(\varphi(x)=x\cdot \prod_{i=1}^k{\frac{p_i-1}{p_i}}\),則 \(\varphi(p^k)=p^{k-1}\varphi(p)=p^{k-1}(p-1)\)
由於是積性函式,所以當 \(i\) 與 \(p\) 互質時,\(\varphi(i\cdot p)=\varphi(i)\varphi(p)\)
我們只需要考慮 \(i\) 與 \(p\) 不互質的情況,即 \(i\ mod\ p=0\) 時。
不妨構造出互質的式子:
\(\varphi(p\cdot i)=\varphi(p^k\cdot\frac{i}{p^{k-1}})=\varphi(p^k)\varphi(\frac{i}{p^{k-1}})=p^{k-1}(p-1) \varphi(\frac{i}{p^{k-1}})\)
\(\varphi(i)=\varphi(p^{k-1}\cdot \frac{i}{p^{k-1}})=p^{k-2}(p-1)\varphi(\frac{i}{p^{k-1}})\)
發現當 \(i\)
int primes[maxn],cnt=0,phi[maxn]; bool notp[maxn]; void make_phi(int n){ notp[1]=true; for(int i=2;i<=n;i++){ if(!notp[i])primes[++cnt]=i,phi[i]=i-1; for(int j=1;j<=cnt;j++){ int tmp=primes[j]*i;if(tmp>n)break; notp[tmp]=true; if(i%primes[j])phi[tmp]=phi[i]*phi[primes[j]]; else{ phi[tmp]=phi[i]*primes[j];break; } } } return ; }
\(\sigma_k(x)\)
\(\sigma_k(x)=\sum_{d|x}d^k\)
\(\sigma_0(x)\),意義為約數的個數。
證明過程類似於上面,直接給出 \(i \ mod \ p=0\) 時的結論:
\(\sigma_0(i\cdot p)=\sigma_0(i)\cdot\frac{d+2}{d+1}\)
其中 \(d=k-1\),也就是 \(i\) 的最小質因子 \(p\) 的次冪。
這其實在我做過的題當中是有應用的,我當時還在感慨題解怎麼這麼胡
這是當時篩法的程式碼,也是核心程式碼:
void init(){
d[1]=1;g[1]=1;
for(int i=2;i<=maxm-5;i++){
if(!notp[i])primes[++cnt]=i,g[i]=1,d[i]=2;
for(int j=1;j<=cnt;j++){
LL k=i*primes[j];
if(k>maxm-5)break;
if(i%primes[j]==0){
notp[k]=true;
g[k]=g[i]+1;
d[k]=1LL*d[i]*(g[i]+2)/(g[i]+1);
break;
}
else{
notp[k]=true;
g[k]=1;
d[k]=d[i]*d[primes[j]];
}
}
}
return ;
}
\(\sigma_1(x)\),意義為 \(x\) 的所有因子的和。
定義式為:
\(\sigma_1(x)=\prod_{p|x}\sum_{i=0}^{c_i}p^i\)
直接給出 \(i\ mod\ p=0\) 時的式子。
\(\sigma_1(p\cdot i)=\frac{\sigma_1(i)}{\sigma_1(p^{k-1)}}\cdot \sigma_1(p^k)\)
其實就是按照思路展開定義求解,因為沒有好用的化簡來處理。
可以預處理快速冪,然後 \(\text O(1)\) 查詢。
貼一張 \(gyx\) 學長的 pdf 截圖: