Note -「狄利克雷前缀和」

学到一个诡异东西,当个 Trick 处理用吧。

现在有一个形如 \(\sum \limits _{i = 1} ^{n} \sum \limits _{d | i} f(d)\) 的柿子,不难发现可以 \(O (n \sqrt n)\) 的算出来。

但是这个时间复杂度还不够优秀(什

考虑记 \(s(i) = \sum \limits _{d|i} f(d)\)。如果 \(f(x)\) 能对 \(f(y)\) 产生贡献,当且仅当 \(x\) 的所有质因数次数都低于或等于 \(y\) 的对应质因数次数。

那么我们就有 \(s(i) = \sum \limits _{\mu(p) = -1} \sum \limits _{d \times p = i} f(d)\)。于是就可以类线性筛(高维前缀和)的做法求解了,时间复杂度 \(O(n \log \log n)\)

for (int i = 1; i <= n; i++)
    s[i] = f[i];
for (int i = 1; i <= Len && Num[i] <= n; i++)
    for (int j = 1; j * Num[i] <= n; j++)
        s[j * Num[i]] += s[j];

其中 Num 为质数表,Len 为质数表大小,可以使用各种筛法预处理。

同理可做 \(\sum \limits _{i = 1} ^{n} \sum \limits _{i | d} f(d)\)

for (int i = 1; i <= n; i++)
    s[i] = f[i];
for (int i = 1; i <= Len && Num[i] <= n; i++)
    for (int j = n / Num[i]; j >= 1; j--)
        s[j] += s[j * Num[i]];

两种结构的求解方式分别被称为狄利克雷前缀和和狄利克雷后缀和。

posted @ 2022-07-15 16:37  STrAduts  阅读(123)  评论(0)    收藏  举报