筛法求常见积性函数

在筛法中,一个数由它的因子筛出来,因此如果数论函数f(n)与f(x),f(y)有关,其中 x ⋅ y = n x\cdot y=n xy=n,则一般可以通过x、y筛出n的函数值。

在这之中,欧拉筛法中每个数都由其最小质因子筛出,应用范围较广:

定义 L P F ( x ) LPF(x) LPF(x)表示x的最小质因子,欧拉筛法可以求出积性函数,需要:

  1. p ∈ P , f ( p ) p\in\mathbb{P},f(p) pP,f(p)容易求。
  2. 当积性函数 f f f有: p = L P F ( n ) , n = x ⋅ p p=LPF(n),n=x\cdot p p=LPF(n),n=xp,已知 f ( x ) , f ( p ) f(x),f(p) f(x),f(p),有 p ∣ x p|x px(也就是p与x不互质)时, f ( n ) f(n) f(n)容易求。

其他筛法也可以求一部分积性函数,以下所述筛法,均为欧拉筛。

筛法求欧拉函数

  1. 对于 p ∈ P , φ ( p ) = p − 1 p\in\mathbb{P},\varphi(p)=p-1 pP,φ(p)=p1
  2. 且由欧拉函数的性质4的推论2可知,一个数 p ⋅ x p\cdot x px的欧拉函数值可以欧拉筛筛出来:

代码如下:

#include<iostream>
#include<vector>
#include<cmath>
using namespace std;
vector<int> a;
bool vis[105];
int phi[105];
void Euler(int n) {
	for(int i=2;i<=n;i++) {
		if(!vis[i]) 
			phi[i]=i-1,a.push_back(i);
		for(auto&j:a) {
			int m=i*j;
			if(i*j>100) break;
			vis[m]=true;
			if(i%j==0) {
				phi[m]=j*phi[i];
				break;
			}
			else
				phi[m]=phi[i]*phi[j];
		}
	}
}
int main() {
	int n;
	cin>>n;
	phi[1]=1;
	Euler(n);
	for(int i=1;i<=n;i++)
		cout<<i<<": "<<phi[i]<<endl;
	return 0;
}

筛法求欧拉函数常用于欧拉反演莫比乌斯反演

筛法求莫比乌斯函数

  1. 对于 p p p μ ( p ) = − 1 \mu(p)=-1 μ(p)=1
  2. 对于 x = i ⋅ j x=i\cdot j x=ij,其中 j j j x x x的质因子。
    i ⊥ j : μ ( x ) = μ ( i ) ⋅ μ ( j ) = − μ ( i ) i\perp j:\mu(x)=\mu(i)\cdot\mu(j)=-\mu(i) ij:μ(x)=μ(i)μ(j)=μ(i)
    否则,x有相同质因子, μ ( x ) = 0 \mu(x)=0 μ(x)=0

因此可以线性筛莫比乌斯函数:

#include<iostream>
#include<vector>
#include<cstdio>
const int N=10000000;
using namespace std;
bool vis[N+5];
int mu[N+5];
vector<int> a;
int pre[N+5];
void Euler() {
	mu[1]=1;
	for(int i=2;i<=N;i++) {
		if(!vis[i])
			mu[i]=-1,
			a.push_back(i);
		for(auto&j:a) {
			int x=i*j;
			if(x>N) break;
			vis[x]=true;
			if(i%j==0) break;
			mu[x]=-mu[i];
		}
	}
	for(int i=1;i<=N;i++) pre[i]=pre[i-1]+mu[i];
}
using namespace std;
int main() {
	Euler();
	int n;
	cin>>n;
	for(int i=1;i<=n;i++)
		printf("%d\n",mu[i]);
	return 0;
}

线性筛莫比乌斯函数常用于莫比乌斯反演

线性筛约数个数函数

约数个数函数 σ 0 \sigma_0 σ0用函数 d d d表示

约数个数定理

对于 x x x有标准分解式, x = ∏ i = 1 s p i a i x=\overset{s}{\underset{i=1}\prod}p_i^{a_i} x=i=1spiai d ( x ) = ∏ i = 1 s a i + 1 d(x)=\overset{s}{\underset{i=1}\prod}{a_i+1} d(x)=i=1sai+1

这个定理很明显,对于 x x x的质因子 p i p_i pi,可以取 [ 0 , a i ] [0,a_i] [0,ai] p i p_i pi,作为 x x x的一个约数的一部分,因此共有 a i + 1 a_i+1 ai+1种可能,应用乘法原理,立即得到上述结论。

线性筛约数个数函数

  1. d ( p ) = 2 d(p)=2 d(p)=2
  2. i ⋅ j = x , j = L P F ( x ) i\cdot j=x,j=LPF(x) ij=x,j=LPF(x)
    i ⊥ j : d 是积性函数, d ( x ) = d ( i ) ⋅ d ( j ) i\perp j:d是积性函数,d(x)=d(i)\cdot d(j) ij:d是积性函数,d(x)=d(i)d(j)
    否则:设 f x f_x fx表示 L P F ( x ) LPF(x) LPF(x)的出现次数,则根据约数个数定理:
    d ( x ) = ∏ k = 1 s a k + 1 = ( f x + 1 ) ∏ k = 2 s a k + 1 = ( f x + 1 ) ( ( f i + 1 ) ∏ k = 2 s a k + 1 f i + 1 ) = ( f x + 1 ) d ( i ) f i + 1 = d ( i ) f i + 1 ( f x + 1 ) d(x)=\overset{s}{\underset{k=1}\prod}{a_k+1}=(f_x+1)\overset{s}{\underset{k=2}\prod}{a_k+1}=(f_x+1)\left(\frac {\left(f_i+1\right)\overset{s}{\underset{k=2}\prod}{a_k+1}}{f_i+1}\right)=(f_x+1)\frac {d(i)}{f_i+1}=\frac {d(i)}{f_i+1}(f_x+1) d(x)=k=1sak+1=(fx+1)k=2sak+1=(fx+1) fi+1(fi+1)k=2sak+1 =(fx+1)fi+1d(i)=fi+1d(i)(fx+1)

(LPF(x)的出现次数,指LPF(x)在标准分解式中的指数)

因此筛约数个数需要同时维护 f f f d d d f f f很好维护。

线性筛约数和函数

约数和函数用 σ 1 \sigma_1 σ1表示,这里简写为 σ \sigma σ

约数和定理

对于 x x x有标准分解式, x = ∏ i = 1 s p i a i x=\overset{s}{\underset{i=1}\prod}p_i^{a_i} x=i=1spiai σ ( x ) = ∏ i = 1 s ∑ j = 0 a i p i j \sigma(x)=\overset{s}{\underset{i=1}\prod}{\overset{a_i}{\underset{j=0}\sum}}p_i^j σ(x)=i=1sj=0aipij

设状态 x i x_i xi表示考虑完前i个质因子,转移到 x i + 1 x_{i+1} xi+1的权值分别为 p i + 1 0 , p i + 1 1 , . . . , p i + 1 a i p_{i+1}^0,p_{i+1}^1,...,p_{i+1}^{a_i} pi+10,pi+11,...,pi+1ai(表示在这个约数中,质因子 p i + 1 p_{i+1} pi+1选取了k次,为 p i + 1 k p_{i+1}^k pi+1k,当然可以不选,权值为1),应用广义乘法原理容易证明。

线性筛约数和函数

  1. σ ( p ) = p + 1 \sigma(p)=p+1 σ(p)=p+1
  2. i ⋅ j = x , j = L P F ( x ) i\cdot j=x,j=LPF(x) ij=x,j=LPF(x)
    i ⊥ j : σ ( x ) = σ ( i ) ⋅ σ ( j ) i\perp j:\sigma(x)=\sigma(i)\cdot\sigma(j) ij:σ(x)=σ(i)σ(j)
    否则:设 f x f_x fx表示 L P F ( x ) LPF(x) LPF(x)的出现次数,根据约数和定理:
    σ ( x ) = ∏ k = 1 s ∑ x = 0 a k p k x = ∑ k = 0 f x j k ( ∏ k = 2 s    ∑ x = 0 a k p k x ) = ∑ k = 0 f x j k ( ∑ x = 0 f i j x ∏ k = 2 s    ∑ x = 0 a k p k x ∑ x = 0 f i j x ) = ∑ k = 0 f x j k ( σ ( i ) ∑ k = 0 f i j k ) \sigma(x)=\overset{s}{\underset{k=1}\prod}{\overset{a_k}{\underset{x=0}\sum}}p_k^x={\overset{f_x}{\underset{k=0}\sum}}j^k\left(\overset{s}{\underset{k=2}\prod}\;{\overset{a_k}{\underset{x=0}\sum}}p_k^x\right)={\overset{f_x}{\underset{k=0}\sum}}j^k\left(\frac{{{\overset{f_i}{\underset{x=0}\sum}j^x}}\overset{s}{\underset{k=2}\prod}\;{\overset{a_k}{\underset{x=0}\sum}}p_k^x}{{{\overset{f_i}{\underset{x=0}\sum}j^x}}}\right)={\overset{f_x}{\underset{k=0}\sum}}j^k\left(\frac{\sigma(i)}{{{\overset{f_i}{\underset{k=0}\sum}j^k}}}\right) σ(x)=k=1sx=0akpkx=k=0fxjk(k=2sx=0akpkx)=k=0fxjk x=0fijxx=0fijxk=2sx=0akpkx =k=0fxjk k=0fijkσ(i)
    g ( n ) g(n) g(n)表示 ∑ k = 0 f n L P F ( n ) k {\overset{f_n}{\underset{k=0}\sum}LPF(n)^k} k=0fnLPF(n)k,上式可继续化为: g ( x ) σ ( i ) g ( i ) g(x)\frac {\sigma(i)} {g(i)} g(x)g(i)σ(i)

我们发现 f f f并没有参与计算,因此筛约数和只要同时维护 σ , g \sigma,g σ,g,g很好维护。

筛法求整除函数

整除函数用 σ k \sigma_k σk表示。

整除函数定理

我们注意到 x = ∏ i = 1 s p i a i x=\overset{s}{\underset{i=1}\prod}p_i^{a_i} x=i=1spiai,有 x k = ( ∏ i = 1 s p i a i ) k = ∏ i = 1 s p i k ⋅ a i x^k=\left(\overset{s}{\underset{i=1}\prod}p_i^{a_i}\right)^k=\overset{s}{\underset{i=1}\prod}p_i^{k\cdot a_i} xk=(i=1spiai)k=i=1spikai,因此对于每个数的贡献,可以拆开成它的质因子的k次幂来算。

  • 对于 x x x有标准分解式, x = ∏ i = 1 s p i a i x=\overset{s}{\underset{i=1}\prod}p_i^{a_i} x=i=1spiai σ k ( x ) = ∏ i = 1 s    ∑ j = 0 a i p i k ⋅ j \sigma_k(x)=\overset{s}{\underset{i=1}\prod}\;{\overset{a_i}{\underset{j=0}\sum}}p_i^{k\cdot j} σk(x)=i=1sj=0aipikj

设状态 x i x_i xi表示考虑完前i个质因子,在这个约数中,下一个质因子选取了c次,就是 p i + 1 c p_{i+1}^c pi+1c,转移到 x i + 1 x_{i+1} xi+1的权值为 ( p i + 1 c ) k \left(p_{i+1}^c\right)^k (pi+1c)k,不选权值为1,应用广义乘法原理容易证明。

整除函数定理是约数和定理、约数个数定理的一般情况。

筛法求整除函数

  1. σ k ( p ) = p k + 1 \sigma_k(p)=p^k+1 σk(p)=pk+1
  2. i ⋅ j = x , j = L P F ( x ) i\cdot j=x,j=LPF(x) ij=x,j=LPF(x)
    i ⊥ j : σ ( x ) = σ ( i ) ⋅ σ ( j ) i\perp j:\sigma(x)=\sigma(i)\cdot\sigma(j) ij:σ(x)=σ(i)σ(j)
    否则:设 g ( X ) = ∑ i = 0 L P F ( X ) 的出现次数 L P F ( x ) k ⋅ i g(X)=\overset{LPF(X)的出现次数}{\underset{i=0}\sum }LPF(x)^{k\cdot i} g(X)=i=0LPF(X)的出现次数LPF(x)ki
    σ k ( x ) = ∏ i = 1 s    ∑ j = 0 a i p i k ⋅ j = g ( x ) ∏ i = 2 s    ∑ j = 0 a i p i k ⋅ j = g ( x ) ( g ( i ) ∏ i = 2 s    ∑ j = 0 a i p i k ⋅ j g ( i ) ) = g ( x ) ⋅ σ k ( i ) g ( i ) \sigma_k(x)=\overset{s}{\underset{i=1}\prod}\;{\overset{a_i}{\underset{j=0}\sum}}p_i^{k\cdot j}=g(x)\overset{s}{\underset{i=2}\prod}\;{\overset{a_i}{\underset{j=0}\sum}}p_i^{k\cdot j}=g(x)\left(\frac{g(i)\overset{s}{\underset{i=2}\prod}\;{\overset{a_i}{\underset{j=0}\sum}}p_i^{k\cdot j}}{g(i)}\right)=g(x)\cdot\frac{\sigma_k(i)}{g(i)} σk(x)=i=1sj=0aipikj=g(x)i=2sj=0aipikj=g(x) g(i)g(i)i=2sj=0aipikj =g(x)g(i)σk(i)

筛法求整除函数需要同时维护 g , σ k g,\sigma_k g,σk g g g很容易维护。

后记

于是皆大欢喜。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值