ICode9

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

Dirichlet 前缀和的几种版本

2020-02-24 13:55:08  阅读:294  来源: 互联网

标签:Dirichlet 前缀 int sum 因子 版本 转移


【模板】Dirichlet 前缀和


\[ B[i] = \sum_{d|i} A[d] \]
$ n \le 2\times 10^{7} $

看代码:

for( int i = 1 ; i <= en && pri[i] <= n ; ++ i ) {
        for (int j = 1; j * pri[i] <= n; ++j) {
            B[j * pri[i]] += B[j];
        }
    }

为啥这么做它是对的呢?发现每个数字会被它除以所有质因子转移到,并且是按照质因子从小到大来的。

所以这个代码相当于,对所有质因子递归求,然后对对所有质因子搞前缀和。

形式和 埃筛 一样,复杂度也是 $ O(n\log\log n) $

然后考虑这个
\[ B[i] = \sum_{i|d} A[d] \]
看代码:

for( int i = 1 ; i <= en && pri[i] <= n ; ++ i ) {
        for (int j = n / pri[i]; j; --j) {
            B[j] += B[j * pri[i]];
        }
    }

首先,我们发现最主要的区别在于,我们应当从 一个数字本身 转移到 这个数字除以所有质因子。因为是从大到小转移的,所以也需要逆序枚举 $ j $ 。

最后考虑这个:
\[ A[i] = \sum_{d|i} B[d] \]
也是已知 $ A $ 求 $ B $

这种情况其实就是第一种情况反过来,我们也可以直接把循环顺序和转移方法给反过来

for( int i = en ; i ; -- i ) {
        for (int j = n / pri[i]; j ; -- j) {
            B[j * pri[i]] -= B[j];
        }
    }

第二种情况也可以反过来,就不赘述了。

例题:CF585E

标签:Dirichlet,前缀,int,sum,因子,版本,转移
来源: https://www.cnblogs.com/yijan/p/12356665.html

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

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

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

ICode9版权所有