zoukankan      html  css  js  c++  java
  • 神秘技巧:O(n lnln n) 的dirichlet卷积

    要求其中一个是积性函数,另一个可以任意。

    其实就是在质因数分解的意义下做高维前缀和。

    高维前缀和

    对于二维前缀和,我们也许可以直接推 s[i][j]=s[i-1][j]+s[i][j-1]-s[i-1][j-1]+a[i][j]

    而我们也可以

    s[i][j]=s[i][j-1]+a[i][j]

    然后

    s[i][j]=s[i-1][j]+a[i][j]

    以实现二维的前缀和。

    换句话说我们可以先枚举维,然后对每一维做前缀和。

    这里咋做

    我们设 (f) 是那个积性函数,(g) 是任意的。

    首先我们枚举“维”。维是啥?自然就是每个质数

    注意到一个积性函数在 (p^1,p^2...p^k) 处的值是不确定的。我们需要枚举它,相当于钦点 (p) 的次数。然后做一个如下操作:

    (g(i) imes f(p^k) o g(i imes p^k))

    注意到这里钦点 (p^k) 是指恰好 (f) 那里的 (p) 就是 (k) 次。所以我们需要倒着枚举 (i),类似背包的考虑,否则会导致重复贡献。

    然后就枚举质数 (p),倒着枚举 (i),枚举 (p^k),做一个前缀和就行了。

    这样的复杂度据说是 (O(nloglog n)) 的。实际跑出来也比 (O(nln n)) 快很多。

    特殊情况

    如果 (f) 是完全积性函数,那你只需要这样做:

    for(p: primes)
    {
        for(int i=1;i<=n/p;++i)
        {
            g[i*p]+=g[i]*f[p];
        }
    }
    

    同样是 (O(nloglog n)) ,常数略小些。

  • 相关阅读:
    学习的原动力
    “六顶思考帽”给我的启示
    关于DataSet与Strongly typed DataSet几点思考(原创)
    设计模式之Singleton和Factory
    CentOS修改网络配置
    Proxmox VE(PVE)安装教程
    CentOS开启SELinux导致samba无法访问的解决办法
    nano编辑器使用教程
    CentOS 如何挂载硬盘
    PVE硬盘直通
  • 原文地址:https://www.cnblogs.com/LightningUZ/p/15394594.html
Copyright © 2011-2022 走看看