• 杜教筛


    目录

    目录地址

    上一篇

    下一篇


    杜教筛

    我们考虑计算 (displaystyle ans=sum_{i=1}^noldsymbol f(i),nleq 10^9)

    这种复杂度,首先,线性筛的复杂度肯定是不够了。我们考虑一个更优秀的方法,杜教筛

    杜教筛的条件有三个:

    1. (oldsymbol f) 为积性函数
    2. 存在积性函数 (oldsymbol g) 其前缀和能快速计算
    3. 迪利克雷卷积 (oldsymbol f*oldsymbol g) 能快速计算前缀和

    对于满足上述三个条件的 (oldsymbol f,oldsymbol g) ,我们来这么看:

    (displaystyle F(n)=sum_{i=1}^noldsymbol f(i))

    (displaystyle sum_{i=1}^n(oldsymbol f*oldsymbol g)(i)=sum_{i=1}^nsum_{dmid i}oldsymbol f({iover d})oldsymbol g(d)=sum_{d=1}^nsum_{i=1}^n[dmid i]oldsymbol f({iover d})oldsymbol g(d))

    (displaystyle herefore sum_{i=1}^n(oldsymbol f*oldsymbol g)(i)=sum_{d=1}^noldsymbol g(d)sum_{i=1}^{n/d}oldsymbol f({idover d})=sum_{d=1}^noldsymbol g(d)sum_{i=1}^{n/d}oldsymbol f(i)=sum_{d=1}^noldsymbol g(d)cdot F(n/d)=sum_{d=2}^noldsymbol g(d)cdot F(n/d)+oldsymbol g(1)cdot F(n))

    (displaystyle herefore ans=F(n)=oldsymbol g(1)cdot F(n)=sum_{i=1}^n(oldsymbol f*oldsymbol g)(i)-sum_{d=2}^noldsymbol g(d)cdot F(n/d))

    如果满足上述三个条件,则求 (F(n)) 时,(displaystyle sum_{i=1}^n(oldsymbol f*oldsymbol g)(i)) 是可以快速计算的,(oldsymbol g(d)) 也是可以用整出分块优化,并快速计算前缀和的,(F(n/d)) 可以递归求解,又由于 (n/d) 的取值级别为 (sqrt n)((n/d)/g=n/gd) 也为 (n/d) 的一种情况

    因此,我们可以通过记忆化来优化,最后经过证明,复杂度可以压缩到 (O(n^{3over 4}))

    但是还可以更优:

    我们预处理 (n^{2over 3}) 范围内的 (F(n)) 值,复杂度即可优化到 (O(n^{2over 3}))


    杜教筛的实现

    我们整合一下思路:

    1. 找到符合条件的 (oldsymbol g)
    2. 筛出 (n^{2over 3}) 范围内的函数前缀和
    3. 采用记忆化,若 (F(n)) 小于 (n^{2over 3})(F(n)) 已筛出,则直接返回
    4. 先算出 (displaystyle sum_{i=1}^n(oldsymbol f*oldsymbol g)(i)) 的值
    5. 再调用整除分块,实现递归求解
  • 相关阅读:
    Java 基础 ------- 面向对象(三) 继承
    虚拟机安装系统--- 安装VMware Tools(五)
    'sqlplus'不是内部或外部命令,也不是可运行的程序
    点餐系统(java基础、数据库、jsp、servlet)
    jsp页面pageContext.setAttribute报错
    Spring事务管理(编码式、配置文件方式、注解方式)
    并发控制
    Spring整合JDBC(连接池、JDBC模板、Dao配置到Spring容器、配置文件的优化)
    Spring的aop思想(名词、aop的配置)
    spring:spring的核心API
  • 原文地址:https://www.cnblogs.com/JustinRochester/p/12508796.html
Copyright © 2020-2023  润新知