• 从基础数论函数说起2:杜教筛


    前置要求

    从基础数论函数说起1:整除分块、数论函数、狄利克雷卷积

    杜教筛

    一部分数论题会问一个数论函数的前缀和,不妨令其为 (S(n)=sumlimits_{i=1}^n f(i)) 。有时直接求会比较困难。

    杜教筛是通过构建一个函数 (g)(f*g) 的前缀和能快速( (O(1)) )求出。这样能在低于线性的复杂度内求解 (S(n))

    具体地来说就是:

    [egin{aligned} sumlimits_{k=1}^{n}sumlimits_{ij=k}f(i)g(j)=sumlimits_{ijleqslant n}f(i)g(j)=sumlimits_{i=1}^n g(i)S(lfloorfrac{n}{i} floor) end{aligned} ]

    那么

    [g(1)S(n)=sumlimits_{ijleqslant n}f(i)g(j)-sumlimits_{i=2}^ng(i)S(lfloorfrac{n}{i} floor) ]

    好像还是没有讲清楚……

    举个例子:

    比方说 (f=mu)(S(n)=sumlimits_{i=1}^n f(i)) 。那么可以构造 (g=id_0) ,那么有

    [g(1)S(n)=sumlimits_{i=1}^n (f*g)(i) - sumlimits_{i=2}^n g(1)S(lfloorfrac{n}{i} floor) ]

    可以得到

    [S(n)=1-sum_{i=2}^n S(lfloorfrac{n}{i} floor) ]

    时间复杂度

    计算 (S(n)) 的时候,需要知道 (S(frac{n}{i}),iin (2, n)) 。这个可以进行整除分块。也就是说,假设我们已经知道了 (S(1cdots n-1)) ,那么计算 (S(n)) 的复杂度是 (O(sqrt{n})) 的。

    (S(n)) 分为两部分考虑。 当 (igeqslant sqrt{n}) 时, (frac{n}{i}leqslant n) 。那么假设把 (S(1cdotssqrt{n})) 全算了,时间复杂度是 (O(sumlimits_{i=1}^{sqrt{n}} sqrt{i})) 的。

    再考虑 (ileqslant sqrt{n}) 的情况。由于 (lfloorfrac{lfloorfrac{n}{i} floor}{j} floor=lfloorfrac{n}{ij} floor) ,那么下标大于 (sqrt{n})(S) 在递归过程中 总共 只会被访问到 (O(sqrt{n})) 个。那么求出这 (O(sqrt{n})) 个的时间复杂度是 (O(sumlimits_{i=1}^{sqrt{n}} sqrt{frac{n}{i}}))

    后一部分的复杂度显然大于前一部分。所以总的时间复杂度是

    [O(sumlimits_{i=1}^{sqrt{n}} sqrt{frac{n}{i}})approx O(int_{0}^{sqrt{n}}sqrt{frac{n}{x}}dx)=O(n^{frac{3}{4}}) ]

    而实际上可以做得更好。前面计算第一部分的时候,假设了计算了所有的 (S(1cdotssqrt{n})) 。但最后计算的时候,仍然是舍去的。不妨考虑稍微多预处理一点,来换取总的较小的复杂度。

    根据前人经验,用线性筛预处理前 (n^{frac{2}{3}}) 项。那么预处理的时间复杂度是 (O(n^{frac{2}{3}})) 。然后后面一部分的复杂度就变为了

    [O(sumlimits_{i=1}^{n^{frac{1}{3}}} frac{n}{i})approx O(int_{i=0}^{n^{frac{1}{3}}} sqrt{frac{n}{x}} dx) = O(n^{frac{2}{3}}) ]

    优化常数和空间

    由于上面提到的, (lfloorfrac{lfloorfrac{n}{i} floor}{j} floor=lfloorfrac{n}{ij} floor) ,需要求出的 (S) 的下标都是 (n) 的约数。所以可以将下标大于 (sqrt{n})(S) 存在另一个数组的 (frac{n}{i}) 里。这样就省去了 hash 或者 map 。

  • 相关阅读:
    python升级安装后的yum的修复
    leetCode 47.Permutations II (排列组合II) 解题思路和方法
    MySQL源代码解读
    MySQL快速建立测试表
    MySQL登陆小问题
    MySQL查看当前用户、存储引擎、日志
    【博客编辑工具】
    mysql5.7执行sql语句出现only_full_group_by错误
    mysql查询出来的某一列合并成一个字段
    动态生成多选框
  • 原文地址:https://www.cnblogs.com/chy-2003/p/11832146.html
Copyright © 2020-2023  润新知