Live2D

积性筛

一些定义

  • 数论函数:定义域为正整数的函数。
  • 积性函数:满足\(f(a)f(b)=f(ab)\ (gcd(a,b)=1)\)的数论函数。
  • 积性筛:在低于线性的时间内求出积性函数前缀和的奇妙算法。

一些积性函数

  • \(\varphi(x)\):欧拉函数。
  • \(\mu(x)\):莫比乌斯函数。
  • \(\epsilon(x)\):元函数。\(\epsilon(x)=\delta_{x1}\)
  • \(d(x)\):约数函数。\(d(x)=\sum_{d|x}1\)
  • \(\sigma(x)\):约数和函数。\(\sigma(x)=\sum_{d|x}d\)
  • \(I(x)\):恒等函数。\(I(x)=1\)
  • \(id(x)\):单位函数。\(id(x)=x\)

狄利克雷卷积

  • 两个数论函数\(f(x),g(x)\)的狄利克雷卷积定义为:\(f*g=\sum_{d|n}f(d)g(\frac nd)\)
  • 显然,狄利克雷卷积满足交换律、结合律、分配律。并且我们不难发现一个性质:两个积性函数的狄利克雷卷积依然是积性函数。

杜教筛

算法流程

  • \(S(n)=\sum_{i=1}^n f(i)\)。我们要求一个\(S(n)\)
  • 设有另一个积性函数\(g\),并设\(h=f*g\),则有:

\[\sum_{i=1}^nh(i)=\sum_{i=1}^n\sum_{d|i}f(d)g(\frac id)=\sum_{d=1}^ng(d)\sum_{i=1}^{\lfloor\frac nd\rfloor}f(i)=\sum_{d=1}^ng(d)S(\lfloor\frac nd\rfloor) \]

  • 因此,\(g(1)S(n)=\sum_{i=1}^nh(i)-\sum_{d=2}^ng(d)S(\lfloor\frac nd\rfloor)\)
  • 由于\(g\)是积性函数,\(g(1)=1\),所以\(S(n)\)就等于右式。

  • 对于\(\sum h(i)\),我们要有一个快速求它的算法(一般要求时间不超\(O(\sqrt n)\));而对于被减数,我们可以先分块,然后递归求解\(S(\lfloor\frac nd\rfloor)\)。由于\(\lfloor\frac {\lfloor\frac ab\rfloor}c\rfloor=\lfloor\frac a{bc}\rfloor\),我们算过的\(S(x)\)一定满足\(x=\lfloor\frac nd\rfloor(d\in[1,n])\),故可以用两个桶(一个是\(≤\sqrt n\)的,一个是\(>\sqrt n\)的,当然也可以合成一个桶)记忆化一下。
  • 空间复杂度显然\(O(\sqrt n)\)
  • 时间的话,可以发现\(x=\lfloor\frac nd\rfloor(d\in[1,n])\)只有\(O(\sqrt n)\)种取值,而且它们都是算过一次就不再算了(记忆化)。因此,\(T(n)=\sum_{i=1}^{\sqrt n}O(\sqrt i)+O(\sqrt{\lfloor\frac ni\rfloor})\)。可以求一个定积分,便知\(T(n)=O(n^{\frac 34})\)
  • 如果先用线筛预处理出前\(n^{\frac 23}\)项,剩余部分的时间复杂度为\(O(\int_0^{n^{\frac 13}}\sqrt{\frac nx}dx)=O(n^{\frac 23})\)

简单例题

T1
  • \(S(n)=\sum_{i=1}^n\mu(i)\)
  • 我们知道\(\mu\)有个性质:\(\mu*I=\epsilon\)。那么直接套公式便可得:\(S(n)=1-\sum_{d=2}^nS(\lfloor\frac nd\rfloor)\)
T2
  • 定义\(f(n)=n\varphi(n)\),求\(S(n)=\sum_{i=1}^nf(i)\)
  • \(h=f*id\),可知\(h(n)=\sum_{d|n}n\varphi(d)=n^2\)。则:\(S(n)=\frac{n(n+1)(2n+1)}6-\sum_{d=2}^ndS(\lfloor\frac nd\rfloor)\)
T3:51nod2026
  • 题目其实是要求\((S(n)=\sum_{i=1}^nf(i))^2\)
  • 稍微推一下式子,\(S(n)=\sum_{i=1}^n\sum_{d|i}d\mu(d)=\sum_{d=1}^nd\mu(d)\lfloor\frac nd\rfloor\)。后面\(\lfloor\frac nd\rfloor\)可以分块来处理,现在我们要处理的只是若干个\(s(x)=\sum_{d=1}^xd\mu(d)\)而已(而且这些\(x\)也都是\(n\)整除某一个数得来)。
  • 依然让它卷上\(id\)\(h(n)=\sum_{d|n}n\mu(d)=\epsilon(n)\)。则:\(s(n)=1-\sum_{d=2}^ndS(\lfloor\frac nd\rfloor)\)
#include <cmath>
#include <cstdio>
#define fo(i,a,b) for(int i=a;i<=b;i++)
using namespace std;

const int M=1e5,N=2e5,mo=1e9+7;
int n,k,s[N],S;
bool v[N];

int C(int x) {return x<=k?M+x:n/x;}
int P(int&x,int y) {x=(1ll*x+y)%mo;}
void gets(int x)
{
	v[C(x)]=s[C(x)]=1;
	for(int i,l=2,r; l<=x; l=r+1)
	{
		r=x/(i=x/l);
		if(!v[C(i)]) gets(i);
		P(s[C(x)],mo-1ll*(l+r)*(r-l+1)/2%mo*s[C(i)]%mo);
	}
}

int main()
{
	scanf("%d",&n), k=sqrt(n);
	gets(n);
	for(int i,l=1,r; l<=n; l=r+1)
	{
		r=n/(i=n/l);
		P(S,1ll*i*(1ll*mo+s[C(r)]-s[C(l-1)])%mo);
	}
	printf("%lld",1ll*S*S%mo);
}

Min_25筛

前言

  • 16年rzz在集训队论文里发明了个洲阁筛,它可以在\(O(\frac{n^{\frac 34}}{\log n})\)的时间内筛出个性质较难发现的积性函数的前缀和。
  • 不过zzt觉得它又臭又长,于是在18年集训队论文里引进了Min_25发明的Min_25筛。
  • 据说是洲阁筛的精简版。

算法简介

  • 首先我们须保证\(f(p^c)\)\(p\)是质数)可以快速计算。我们要求\(F(n)=\sum_{i=1}^nf(i)\)
  • \(p_k\)为第\(k\)小的质数。设\(lpf(n)\)\(n\)的最小质因数,\(n=1\)时其值为1;\(F_k(n)=\sum_{i=2}^n[p_k≤lpf(i)]f(i)\)。则可得:
    \begin{aligned} F_{k}(n) &= \sum_{i = 2}^{n} [p_{k} \le \operatorname{lpf}(i)] f(i) \ &= \sum_{\substack{k \le i \ p_{i}^{2} \le n}} \sum_{\substack{c \ge 1 \ p_{i}^{c} \le n}} f\left(p_{i}^{c}\right) ([c > 1] + F_{i + 1}\left(n / p_{i}^{c}\right)) + \sum_{\substack{k \le i \ p_{i} \le n}} f(p_{i}) \ &= \sum_{\substack{k \le i \ p_{i}^{2} \le n}} \sum_{\substack{c \ge 1 \ p_{i}^{c} \le n}} f\left(p_{i}^{c}\right) ([c > 1] + F_{i + 1}\left(n / p_{i}^{c}\right)) + F_{\mathrm{prime}}(n) - F_{\mathrm{prime}}(p_{k - 1}) \ &= \sum_{\substack{k \le i \ p_{i}^{2} \le n}} \sum_{\substack{c \ge 1 \ p_{i}^{c + 1} \le n}} \left(f\left(p_{i}^{c}\right) F_{i + 1}\left(n / p_{i}^{c}\right) + f\left(p_{i}^{c + 1}\right)\right) + F_{\mathrm{prime}}(n) - F_{\mathrm{prime}}(p_{k - 1}) \end{aligned}

  • 现在考虑计算\(F_{prime}(n)=\sum_{2≤p≤n}\)
  • \(G_k(n)=\sum_{i=2}^n[p_k<lpf(i)\lor isprime(i)]f(i)\),即埃氏筛筛完k轮后剩下数的和,则显然\(F_{prime}=G_{\sqrt n}\)。记\(G_0=\sum_{i=2}^nf(i)\)
  • 转移即为: G_{k}(n) = G_{k - 1}(n) - \left[p_{k}^{2} \le n\right] g(p_{k}) (G_{k - 1}(n / p_{k}) - G_{k - 1}(p_{k - 1}))
posted @ 2019-09-26 17:58  Iking123  阅读(224)  评论(0编辑  收藏  举报