杜教筛

我们对于一个要求的数论函数 f(x),定义 S(n)=i=1nf(x)

然后我们考虑构造一个 S(n) 关于 S(ni) 的一个递推式子。

我们发现,对于任意的一个数论函数 g(x) ,我们有:

i=1ndig(d)f(id)=i=1n(g×f)(i)

然后我们考虑先枚举 d

=d=1nk=1kdng(d)f(kdd)

=d=1nk=1ndg(d)f(k)

=d=1ng(d)S(nd)

所以由上面的式子,可以得到一个杜教筛的核心公式:

g(1)S(n)=i=1n(f×g)(i)i=2ng(i)S(ni)

这样我们就可以求一些数论函数的前缀和了。

我们举两个例子:一个 μ 一个 φ

我们先以 μ 为例。

因为 μ×1=e,我们把 f 代入 μ , 把 g 代入 1,可得:

S(n)=i=1ne(i)i=2nS(ni)

=1i=2nS(ni)

然后 φ 同理可以由 φ×1=id 得到:

S(n)=inid(i)i=2nS(ni)

S(n)=(n+1)n2i=2nS(ni)

但是同时,我们还可以用莫比乌斯反演,以达到只需 μ 的前缀和即可。

S(n)=12(i=1nμ(i)ni21)+1

附上 模板题 代码

#include<bits/stdc++.h>
#define ll long long
#define db double
#define filein(a) freopen(#a".in","r",stdin)
#define fileot(a) freopen(#a".out","w",stdout)
#define sky fflush(stdout)
template<class T>
inline void read(T &s){
	s=0;char ch=getchar();bool f=0;
	while(ch<'0'||'9'<ch) {if(ch=='-') f=1;ch=getchar();}
	while('0'<=ch&&ch<='9') {s=s*10+(ch^48);ch=getchar();}
	if(ch=='.'){
		db p=0.1;ch=getchar();
		while('0'<=ch&&ch<='9') {s=s+(ch^48)*p;p*=0.1;ch=getchar();};
	}
	s=f?-s:s;
}
const int N23=1664510+3;
std::vector<int>pri;
int mu[N23];
bool vis[N23];
const int Sz=1145141;
struct hash_map{
	std::vector<int>head,nxt;
	struct node{
		ll v,w;
	};
	std::vector<node>to;
	hash_map(){
		head.resize(Sz+3,-1);
	}
	inline ll & operator [](ll x){
		int u=x%Sz;
		for(int i=head[u];~i;i=nxt[i]){
			int v=to[i].v;
			if(v==x){
				return to[i].w;
			}
		}
		nxt.push_back(head[u]);
		head[u]=to.size();
		to.push_back({x,0});
		return to[to.size()-1].w;
	}
}Smu;
inline void Euler(int n){
	Smu[1]=vis[1]=mu[1]=1;
	for(int i=2;i<=n;++i){
		if(!vis[i]){
			pri.push_back(i);
			mu[i]=-1;
		}
		for(auto it:pri){
			if(i*it>n) break;
			vis[i*it]=1;
			if(i%it){
				mu[i*it]=-mu[i];
			}else{
				mu[i*it]=0;
				break;
			}
		}
	}
	for(int i=2;i<=n;++i){
		Smu[i]=Smu[i-1]+mu[i];
	}
}
inline ll Sum_mu(ll n){
	if(n<N23) return Smu[n]; 
	if(Smu[n]) return Smu[n];
	ll res=0;
	for(ll l=2,r;l<=n;l=r+1){
		r=n/(n/l);
		res+=(r-l+1)*Sum_mu(n/l);
	}
	return Smu[n]=(1ll-res);
}
inline ll Sum_phi(ll n){
	ll res=0;
	for(ll l=1,r;l<=n;l=r+1){
		r=n/(n/l);
		res+=(Sum_mu(r)-Sum_mu(l-1) )*(n/l)*(n/l);
	}
	return (res-1)/2+1;
}
int main(){
	filein(a);fileot(a);
	Euler(N23-3);
	int T;read(T);
	while(T--){
		ll x;read(x);
		printf("%lld %lld\n",Sum_phi(x),Sum_mu(x) );
	}
	return 0;
}
posted @   cbdsopa  阅读(22)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示