其他分享
首页 > 其他分享> > 狄利克雷生成函数

狄利克雷生成函数

作者:互联网

注意本文中用的字母可能和其他博客中有区别。

黎曼zeta函数\(\zeta(x)=\sum_{n\ge 1} \frac{1}{n^x}\)。

手写时本人喜欢写成\(z\)(因为\(\zeta\)太难写),但是在博客中还是正式点吧。


参考资料:

https://zhuanlan.zhihu.com/p/50817119

https://blog.csdn.net/luositing/article/details/109204796


形式

狄利克雷生成函数(DGF)形式:

\[F(x)=\sum_{n\ge 1}\frac{f_n}{n^x}。 \]

以下默认\(n\ge 1,n\in Z\)。

不难发现在这个形式下,如果有\(H(x)=F(x)G(x)\),那么有\(h_n=\sum_{d|n} f_dg_{\frac{n}{d}}\),也就是说\(h\)是\(f,g\)的狄利克雷卷积。


常用数论函数的DGF

当\(\forall n,f_n=1\)时,\(F(x)=\zeta(x)\)。

根据数论函数的基本性质,可以得到

\[\zeta(x)=\prod_p1+p^{-x}+p^{-2x}+\dots=\prod_p\frac{1}{1-p^{-x}} \]

当\(f_n=\mu(n)\)时:根据\(\mu\)的定义可得\(F(x)=\prod_p1-p^{-x}\)。于是有\(F(x)=\frac{1}{\zeta(x)}\)。

当\(f_n=n\)时:\(F(x)=\prod_p\sum_{i\ge 0}\frac{p^i}{p^{ix}}=\prod_p\frac{1}{1-p^{-(x-1)}}=\zeta(x-1)\)。

当\(f_n=\phi(n)\)时:\(F(x)=\prod_p 1+\frac{p-1}{p}\sum_{i\ge 1}\frac{1}{p^{i(x-1)}}=\prod_p\frac{1-p^{-x}}{1-p^{-(x-1)}}=\frac{\zeta(x-1)}{\zeta(x)}\)。

当\(f_n=\sigma_0(n)\)时:\(F(x)=\zeta^2(x)\)。

当\(f_n=\sigma_1(n)\)时:\(F(x)=\zeta(x)\zeta(x-1)\)。

通过这些东西,可以很直观地发现一些性质,什么\(I*\mu=e\),\(I*\phi=id\),\(\sigma_0*\phi=\sigma_1\)之类的。


DGF的运算

加减不说,乘法朴素\(O(n\ln n)\),用类似高维前缀和的方法好像可以做到\(O(n\ln \ln n)\)。

除法:假如有\(H(x)=F(x)G(x)\),已知\(H(x),F(x)\),则有\(h_n=\sum_{d|n,d>1}f_dg_{\frac{n}{d}}+f_1g_n\),移项得到\(g_n\)。时间\(O(n\ln n)\)。

求导、积分:

\[(\frac{f_n}{n^x})'=-\ln n\frac{f_n}{n^x}\\ \int \frac{f_n}{n^x}dx=-\frac{1}{\ln n}\frac{f_n}{n^x} \]

\(\ln n\)似乎不好处理。注意到求导和积分往往是成对存在的,不妨找个\(\ln n\)的替代品。定义\(c(n)\)表示\(n\)的可重质因子个数,用它来替代。这个函数也满足\(\ln\)的部分性质:\(c(1)=0,c(ab)=c(a)+c(b)\)。

它好像没有复刻\(ln\)的全部性质,为什么是对的?以下谈谈本人的感性理解:

当然如果有高深的高等数学知识可以略过

我认为这个疑问都来自于不同质数之间的关系,比如\(\ln 2\neq \ln 3\),然而这里\(c(2)=c(3)=1\)。

但是其实可以把每个质数看成一个维度,其指数为在这一维上的坐标,于是每个数都相当于无限维空间中的一个点。

我们可以把所有数重标号一下,把质因子\(2\)全部换成\(3\),把质因子\(3\)全部换成\(2\),相当于两个维度换一下。如果\(\ln 2\neq\ln 3\)对求导积分之后的结果有影响,不符合对称性,矛盾。

所以并不需要满足\(\ln 2\neq \ln 3\)。

于是变成这样:

\[(\frac{f_n}{n^x})'=c(n)\frac{f_n}{n^x}\\ \int \frac{f_n}{n^x}dx=\frac{1}{c(n)}\frac{f_n}{n^x} \]

求\(\ln\):\(\ln F(x)=\int \frac{F'(x)}{F(x)}dx\)。

求\(exp\):设\(G(x)=e^{F(x)}\),则\(G'(x)=F'(x)G(x)\)。把式子拆开,用类似除法的方式做就行了。


例题

PE639(题解):https://www.cnblogs.com/jz-597/p/14402383.html

LOJ6713. 「EC Final 2019」狄利克雷 k 次根 加强版。下面贴代码:

using namespace std;
#include <bits/stdc++.h>
#define N 1000005
#define mo 998244353
#define ll long long
ll qpow(ll x,ll y=mo-2){
	ll r=1;
	for (;y;y>>=1,x=x*x%mo)
		if (y&1)
			r=r*x%mo;
	return r;
}
int n,k;
ll g[N],f[N];
int p[N],np;
bool inp[N];
int c[N],inv[N];
void init(){
	c[1]=0;
	for (int i=2;i<=n;++i){
		if (!inp[i])
			p[++np]=i,c[i]=1;
		for (int j=1;j<=np && i*p[j]<=n;++j){
			inp[i*p[j]]=1;
			c[i*p[j]]=c[i]+1;
			if (i%p[j]==0)
				break;
		}
	}
	inv[1]=1;
	for (int i=2;i<=n;++i)
		inv[i]=(ll)(mo-mo/i)*inv[mo%i]%mo;
}
void check(ll h[],ll f[],ll g[]){
	static ll t[N];
	for (int i=1;i<=n;++i)
		for (int j=1;i*j<=n;++j)
			(t[i*j]+=f[i]*g[j])%=mo;
	for (int i=1;i<=n;++i)
		if (t[i]!=h[i]){
			printf("****\n");
			exit(0);
		}
}
void getdiv(ll h[],ll f[],ll g[]){
	static ll d[N];
	memset(d,0,sizeof(ll)*(n+1));
	ll t=qpow(g[1]);
	for (int i=1;i<=n;++i){
		d[i]=(d[i]+mo+f[i])*t%mo;
		for (int j=2;i*j<=n;++j)
			(d[i*j]-=d[i]*g[j])%=mo;
	}
	memcpy(h,d,sizeof(ll)*(n+1));
	check(f,g,h);
}
void getln(ll f[],ll g[]){
	static ll g_[N],_f[N];
	for (int i=1;i<=n;++i)
		g_[i]=g[i]*c[i]%mo;
	getdiv(_f,g_,g);
	f[1]=0;
	for (int i=2;i<=n;++i)
		f[i]=_f[i]*inv[c[i]]%mo;
}
void getexp(ll g[],ll f[]){
	static ll d[N];
	memset(d,0,sizeof(ll)*(n+1));
	assert(f[1]==0);
	d[1]=1;
	for (int j=2;j<=n;++j)
		(d[j]+=c[j]*f[j])%=mo;
	for (int i=2;i<=n;++i){
		d[i]=d[i]*inv[c[i]]%mo;
		for (int j=2;i*j<=n;++j)
			(d[i*j]+=c[j]*f[j]%mo*d[i])%=mo;
	}
	memcpy(g,d,sizeof(ll)*(n+1));
}
void getpow(ll h[],ll g[],ll t){
	static ll d[N];
	getln(d,g);
	for (int i=1;i<=n;++i)
		d[i]=d[i]*t%mo;
	getexp(h,d);
}
int main(){
//	freopen("in.txt","r",stdin);
	scanf("%d%d",&n,&k);
	init();
	for (int i=1;i<=n;++i)
		scanf("%lld",&g[i]);
	getpow(f,g,qpow(k));
	for (int i=1;i<=n;++i)
		printf("%lld ",f[i]);
//	printf("\n");
//	getpow(g,f,k);
//	for (int i=1;i<=n;++i)
//		printf("%lld ",g[i]);
//	printf("\n");
	return 0;
}

标签:frac,函数,狄利克,ln,sum,生成,int,zeta,prod
来源: https://www.cnblogs.com/jz-597/p/14403977.html