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]];
两种结构的求解方式分别被称为狄利克雷前缀和和狄利克雷后缀和。

浙公网安备 33010602011771号