Dirichlet相关知识

前言

大概是省选前最后一篇知识点总结的博客。

就是之前没有怎么学懂 Dirichlet 相关的一堆知识点,最后感觉还是要搞搞,不然要是考了直接死亡。

话说还是今年2月yyb学长来讲课的时候才意识到 \([d=1]=\sum _{k|d} \mu(k)\) 其实只是拆 Dirichlet 式子...

反正就是补了一下Dirichlet相关的数论吧。

Dirichlet 卷积

形式是这样的: \(f*g\ (n)=\sum_{k|n} f(k)g(\frac{n}{k})\)

注意对于每一个 \(i\in[1,n]\) 枚举 \(k|i\) 的复杂度是 \(O(n\ln n)\) 的。

要记忆两个最重要的 Dirichlet 的卷积结果:

  • \(id=\ ?\)
  • \([n=1]=\ ?\)

答案:

  • \(id=1* \varphi\)
  • \([n=1]=\varepsilon=1* \mu\)

这个其实也挺重要 :

\(f(n)=\varphi(n) n^k,g(n)=n^{k+1}\)

\[\begin{aligned} f*g\ (n) &=\sum_{d|n} \varphi(d)d^k \left(\frac{n}{d}\right)^{k+1}\\ &=n^k\sum_{d|n} \varphi(d) \left(\frac{n}{d}\right)(\text{这后面的其实就是}\varphi*1)\\ &=n^{k+1} \end{aligned} \]

拆 Dirichlet 式子

虚假的莫反

看到 \(\sum \sum \text{gcd 相关}\) 直接拆就行了,基本比较套路?

举个例子?\((i,j)\) 其实就是 \(\gcd(i,j)\)

\[\begin{aligned} &\sum_{i=1}^n\sum_{j=1}^m\sigma_1((i,j))\\ =&\sum_{d=1}^n\sigma_1(d)\sum_{i=1}^{\lfloor\frac{n}{d}\rfloor}\sum_{j=1}^{\lfloor\frac{m}{d}\rfloor}[(i,j)=1]\\ =&\sum_{d=1}^n\sigma_1(d)\sum_{i=1}^{\lfloor\frac{n}{d}\rfloor}\sum_{j=1}^{\lfloor\frac{m}{d}\rfloor}\sum_{x|(i,j)}\mu(x)\\ =&\sum_{d=1}^n\sigma_1(d)\sum_{i=1}^{\lfloor\frac{n}{d}\rfloor}\sum_{j=1}^{\lfloor\frac{m}{d}\rfloor}\sum_{x|i,x|j}\mu(x)\\ =&\sum_{d=1}^n\sigma_1(d)\sum_{x=1}^{\lfloor\frac{n}{d}\rfloor}\mu(x)\lfloor\frac{n}{dx}\rfloor\lfloor\frac{m}{dx}\rfloor\\ =&\sum_{T=1}^n\lfloor\frac{n}{T}\rfloor\lfloor\frac{m}{T}\rfloor\sum_{d|T}\sigma_1(d)\mu(\frac{T}{d}) \end{aligned} \]

然后根据我们上面的理论,后面的一坨是可以枚举计算的,然后前面就是整除分块了。

当然,如果后面的一坨枚举可能过不去的话,就研究一下能不能筛出来。

杜教筛

\(O(n^{\frac{2}{3}})\) 处理一些数论函数的前缀和,比如上面我们拆 Dirichlet 最后就是要快速求后面一坨的前缀和,而且加上整除分块之后复杂度还是 \(O(n^{\frac{2}{3}})\)

原理其实就是一个式子(设 \(S(n)=\sum_{j=1}^n f(j)\)):

\[\begin{aligned} \sum_{i=1}^{n}(f*g)(i)=&\sum_{i=1}^n\sum_{d|i}f(d)g(\frac{i}{d})\\ =&\sum_{d=1}^n g(d)\sum_{i=1}^{\lfloor\frac{n}{d}\rfloor}f(i)\\ =&\sum_{d=1}^ng(d)S(\lfloor\frac{n}{d}\rfloor) \end{aligned} \]

然后

\[g(1)S(n)=\sum_{i=1}^n(f\ast g)(i)-\sum_{i=2}^ng(i)S\left(\left\lfloor\frac{n}{i}\right\rfloor\right) \]

所以,如果你能快速求 \(f*g\) 的前缀和,\(g\) 的前缀和,后面一波整除分块,就可以求出 \(S\) 的前缀和了。

比如求 \(\varphi\) 的前缀和:

因为 \(\varphi * 1=id\) ,所以 \(f*g\) 的前缀和就是 \(\frac{n(n+1)}{2}\) ,而 \(g\) 的前缀和就是 \(n\) ,所以直接整除分块就可以了。

代码:

unordered_map<int,ll> f;
ll solve(ll x){
	if(x<=N)return phi[x];
	if(f.count(x))return f[x];
	ll ans=1ll*x*(x+1)/2;
	for(ll l=2,r=1;l<=x;l=r+1){
		int st=x/l;r=x/st;
		ans-=solve(st)*(r-l+1);
	}
	return f[x]=ans;
}

题目:

或许难度在推式子。题解

这题还能启发我们在推式子的时候能不能转化成 式子和原来一样,但 \(n\) 变成了 \(\frac{n}{d}\) 之类的。

也就是范围缩小了,最后转化成一个可以处理的特殊情况之类的。

直接看题解吧...

posted @ 2022-03-20 19:22  qwq_123  阅读(39)  评论(0编辑  收藏  举报