好久没更了,刚考完省选有点颓。
杜教筛用于在 的时间内求解某些函数的前缀和。
杜教筛的核心公式如下:
设 为目标函数(即我们要求前缀和的函数)
设 为我们构造的一个函数。
其中 为 与 的狄利克雷卷积。
如果能找到一个合适的积性函数 ,能快速求出 和 ,那么就能使用数论分块递归求解了。
不一定要是积性函数。
假设算 的复杂度为 ,算 的复杂度为 :
通常情况下 和 都为 。
后面的那个可以忽略,于是
众所周知的杜教筛是 的,原因是可以先筛出前 个答案。复杂度变为 ,取 即可。
再看例子前,可以先看看有哪些常作为 的函数。
下面 为 与 的狄利克雷卷积。
由于 ,所以取 ,那么
auto apiadu_sieve_phi = [&](auto& $, tp n) -> tp {
if (n <= m || ps_phi.count(n)) return ps_phi[n];
tp ret = n * (n + 1) / 2;
for (tp l = 2, r; l <= n; l = r + 1) {
r = n / (n / l);
ret -= (r - l + 1) * $($, n / l);
}
return ps_phi[n] = ret;
};
由于 ,所以取 ,那么
auto apiadu_sieve_mu = [&](auto& $, tp n) -> tp {
if (n <= m || ps_mu.count(n)) return ps_mu[n];
tp ret = 1;
for (tp l = 2, r; l <= n; l = r + 1) {
r = n / (n / l);
ret -= (r - l + 1) * $($, n / l);
}
return ps_mu[n] = ret;
};
这是一个经典例子。尽管 不再是积性函数,但我们任然可以杜教筛。
取 ,
于是我们还是可以在常数时间内计算 。
https://www.luogu.com.cn/article/tojxbb76
https://oi-wiki.org/math/number-theory/du/
https://www.luogu.com/article/hjw4837h