积性函数笔记

积性函数:

定义

设f(n)为积性函数,n=ab且(a,b)=1,有f(n)=f(a)*f(b)

完全积性函数

n=ab,即有f(n)=f(a)*f(b),不要求(a,b)=1;

常见函数

\(\epsilon,\phi,d,\sigma,I,\mu,Id\)

迪利克雷卷积

定义

一种数论意义上的卷积,\((f*g)(n)=\sum_{d|n}f(d)*g(n/d)\)

性质

交换律,结合律,分配律。
积性函数的卷积仍为积性函数,但完全积性函数的卷积不一定是完全积性。

莫比乌斯反演

\(\epsilon=I*\mu,\phi=Id*\mu,d=I*I,\sigma=I*Id\)
前两个尤为重要。

常用技巧

\(\sum\limits_{1<=i<=n,1<=j<=m}f((i,j))=\sum\limits_{d=1}^{min(n,m)}g(d)\lfloor {n/d}\rfloor \lfloor {m/d}\rfloor\)

几道例题


要点

\(\epsilon=I*\mu\)

点击查看代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
template<typename T>
void read(T &x){
	x=0;T fl=1;char tmp=getchar();
	while(tmp<'0'||tmp>'9')fl=tmp=='-'?-fl:fl,tmp=getchar();
	while(tmp>='0'&&tmp<='9')x=(x<<1)+(x<<3)+tmp-'0',tmp=getchar();
	x*=fl;
}
const int maxn=1e7+100;
int p[maxn],pr[maxn];
int cnt;
int mu[maxn];
ll sum[maxn];
int n,m;
void solve(){
	p[1]=1,mu[1]=1;
	for(int i=2;i<maxn;i++){
		if(!p[i])mu[i]=-1,p[i]=i,pr[++cnt]=i;
		for(int j=1;j<=cnt&&pr[j]*i<maxn;j++){
			p[i*pr[j]]=pr[j];
			if(p[i]==pr[j]){
				mu[i*pr[j]]=0;
				break;
			}
			else mu[i*pr[j]]=-mu[i];
		}
	}
	for(int i=1;i<maxn;i++)
		sum[i]=sum[i-1]+mu[i];
}
signed main(){
	solve();
	int T;cin>>T;
	while(T--){
		cin>>n>>m;
		if(n>m)swap(n,m);
		ll ans=0;
		for(int l=1;l<=n;l++){
			int r=min(n/(n/l),m/(m/l));
			ans+=(sum[r]-sum[l-1])*(n/l)*(m/l);
			l=r;
		}
		cout<<ans<<endl;
	}
	return 0;
}


要点

与上题同理,
\(Id=I*\phi\)
变量名应该是phi,偷懒没改。。。

点击查看代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
template<typename T>
void read(T &x){
	x=0;T fl=1;char tmp=getchar();
	while(tmp<'0'||tmp>'9')fl=tmp=='-'?-fl:fl,tmp=getchar();
	while(tmp>='0'&&tmp<='9')x=(x<<1)+(x<<3)+tmp-'0',tmp=getchar();
	x*=fl;
}
const int maxn=1e7+100;
int p[maxn],pr[maxn];
int cnt;
int mu[maxn];
ll sum[maxn];
int n,m;
void solve(){
	p[1]=1,mu[1]=1;
	for(int i=2;i<maxn;i++){
		if(!p[i])mu[i]=i-1,p[i]=i,pr[++cnt]=i;
		for(int j=1;j<=cnt&&pr[j]*i<maxn;j++){
			p[i*pr[j]]=pr[j];
			if(p[i]==pr[j]){
				mu[i*pr[j]]=mu[i]*pr[j];
				break;
			}
			else mu[i*pr[j]]=mu[i]*(pr[j]-1);
		}
	}
	for(int i=1;i<maxn;i++)
		sum[i]=sum[i-1]+mu[i];
}
signed main(){
	solve();
	int T;cin>>T;
	while(T--){
		cin>>n>>m;
		if(n>m)swap(n,m);
		ll ans=0;
		for(int l=1;l<=n;l++){
			int r=min(n/(n/l),m/(m/l));
			ans+=(sum[r]-sum[l-1])*(n/l)*(m/l);
			l=r;
		}
		cout<<ans<<endl;
	}
	return 0;
}
posted @ 2022-09-20 22:34  xyc1719  阅读(41)  评论(0)    收藏  举报