ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

神秘技巧:O(n lnln n) 的dirichlet卷积

2021-10-11 19:01:07  阅读:227  来源: 互联网

标签:dirichlet 前缀 卷积 函数 积性 枚举 lnln 质数 log


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

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

高维前缀和

对于二维前缀和,我们也许可以直接推 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)\times f(p^k)\to g(i\times p^k)\)。

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

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

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

特殊情况

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

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

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

标签:dirichlet,前缀,卷积,函数,积性,枚举,lnln,质数,log
来源: https://www.cnblogs.com/LightningUZ/p/15394594.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有