学习笔记:筛法

杜教筛

可以在 \(O(n^{2/3})\) 的时间复杂度内求出某些积性函数的前缀和。

具体地,对于积性函数 \(f\),如果能找到另一个积性函数 \(g\),使得 \(h=f\ast g\) 的前缀和容易计算,那么 \(f\) 就可以杜教筛。

推导

\(f\) 的前缀和 \(F(n)=\sum\limits_{1\le i\le n}f(i)\)\(g\) 的前缀和 \(G(n)=\sum\limits_{1\le i\le n}g(i)\)\(h\) 的前缀和 \(H(n)=\sum\limits_{1\le i\le n}h(i)\)

展开 \(h\) 的前缀和:

\[\begin{align*} H(n)&=\sum\limits_{1\le i\le n}h(i)\\ &=\sum\limits_{1\le i\le n}\sum\limits_{d\mid i}f(i)g(\frac{i}{d})\\ &=\sum\limits_{d=1}^n\sum\limits_{k=1}^{\lfloor n/d\rfloor}f(d)g(k)\\ &=\sum\limits_{1\le d\le n} f(d)\sum\limits_{k=1}^{\lfloor n/d\rfloor}g(k)\\ &=\sum\limits_{1\le d\le n} f(d)G(\lfloor\frac{n}{d}\rfloor)\\ &=f(1)G(n)+\sum\limits_{2\le d\le n}f(d)G(\lfloor\frac{n}{d}\rfloor)\\ &=G(n)+\sum\limits_{2\le d\le n}f(d)G(\lfloor\frac{n}{d}\rfloor)\\ \end{align*} \]

因为全程只是用了 \(f,g\) 这两个符号,所以可以直接交换二者,得到:

\[\begin{align*} H(n)=F(n)+\sum\limits_{2\le d\le n}g(d)F(\lfloor\frac{n}{d}\rfloor) \end{align*} \]

移项,得到:

\[\begin{align*} F(n)=H(n)-\Big(\sum\limits_{2\le d\le n}g(d)F(\lfloor\frac{n}{d}\rfloor)\Big) \end{align*} \]

发现此时 \(F\) 可以利用数论分块和记搜,递归求解了。这就是杜教筛的理论依据。

如何构造 \(g\)

暂时不是很会。 似乎很多时候都选取 \(1\) 来作为 \(g\),常用结论 \(\varphi\ast 1=\text{id},\mu\ast 1=[n=1]\);有时候选 \(\mu\),常用结论 \(\text{id}\ast\mu=\varphi,1\ast\mu=[n=1]\);似乎还有时候会选 \(\text{id}\),常用结论 \((n\cdot\varphi(n))\ast\text{id}=\text{id}^2\),也就是构造平方和。

找不到怎么办?使用 min_25 筛。

代码

P4213 【模板】杜教筛 为例,求 \(\varphi\)\(\mu\) 的前缀和。

对于 \(\mu\),可以取 \(g(n)=1\),于是有 \(h(n)=(\mu\ast g)(n)=[n=1]\);对于 \(\varphi\),同样取 \(g(n)=1\),于是有 \(h(n)=(\varphi\ast g)=n\)

namespace Math{
	
	unordered_map<int,int>mem_phi,mem_mu;
	
	int tot;
	
	int pri[N],mu[N],phi[N];
	bool np[N];
	
	inline void init(int n){
		mu[1]=1,phi[1]=1;
		for(int i=2;i<=n;++i){
			if(!np[i])phi[i]=i-1,pri[++tot]=i,mu[i]=-1;
			for(int j=1;j<=tot&&i*pri[j]<=n;++j){
				np[i*pri[j]]=1;
				if(!(i%pri[j])){phi[i*pri[j]]=phi[i]*pri[j],mu[i*pri[j]]=0;break ;}
				phi[i*pri[j]]=phi[i]*(pri[j]-1),mu[i*pri[j]]=-mu[i];
			}
		}
		for(int i=1;i<=n;++i)mem_phi[i]=mem_phi[i-1]+phi[i],mem_mu[i]=mem_mu[i-1]+mu[i];
		return ;
	}
	
	inline int qry_pre_mu(int n){
		if(mem_mu.count(n))return mem_mu[n];
		int l=2,r=0;
		int res=0;
		for(;l<=n;l=r+1){
			r=n/(n/l);
			res+=qry_pre_mu(n/l)*(r-l+1);
		}
		res=1-res;
		return mem_mu[n]=res;
	}
	
	inline int qry_mu(int l,int r){
		return qry_pre_mu(r)-qry_pre_mu(l-1);
	}
	
	inline int qry_pre_phi(int n){
		if(mem_phi.count(n))return mem_phi[n];
		int l=1,r=0;
		int res=0;
		for(;l<=n;l=r+1){
			r=n/(n/l);
			res+=(n/l)*(n/l+1)/2*qry_mu(l,r);
		}
		return mem_phi[n]=res;
	}
	
}using namespace Math;

为什么不要求 \(g\) 的前缀和也容易求?

P4318 为例,此题可以取 \(g(n)=[\exists k,k^2=n]\),这样构造使得 \(h(n)=1\) 恒成立,进而有 \(H(n)=n\);同时在枚举杜教筛最后那个式子里的 \(d\) 时只需要枚举平方因子并去掉 \(g\),进而规避掉 \(g\) 的前缀和。

min_25 筛

黑科技。咕咕咕。

PN 筛

黑科技。咕咕咕。

posted @ 2026-07-10 19:23  DX3906_ourstar  阅读(6)  评论(0)    收藏  举报