1. 程式人生 > 其它 >[總結] 線性篩與積性函式

[總結] 線性篩與積性函式

[總結] 線性篩與積性函式

利用線性篩中一個數僅僅被它最小的質因子篩掉的性質,結合積性函式的特殊性質,往往可以預處理出積性函式的值。

\(\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\)

的最小質因子 \(p\) 的次數為 \(k-1\)\(\varphi(p\cdot i)=p\cdot \varphi(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\) 的次冪。

這其實在我做過的題當中是有應用的,我當時還在感慨題解怎麼這麼胡

CF920F SUM and REPLACE

這是當時篩法的程式碼,也是核心程式碼:

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 截圖: