高维前缀和

前缀和

迪利克雷前缀和:给定 \(f(1),f(2),\dots f(n)\),求 \(g(d)=\sum\limits_{x\mid d}f(x)\)\(d\in[1,n]\)

问题中的 \(g\) 就是就是 \(f\) 的迪利克雷前缀和,直接求是 \(O(n\ln n)\) 的,但可以做到 \(O(n\log\log{n})\)

\(x=\prod p_i^{\alpha_i}\)\(y=\prod p_i^{\beta_i}\),那么 \(x\) 贡献到 \(y\) 当且仅当 \(\forall i,~\alpha_i\le \beta_i\)。因此这就是一个质因数分解之后,指数的高位前缀和问题,先筛出 \(\le n\) 的所有质数,然后按位依次前缀和即可(每个质数是一”位“)

for(int i = 1; i <= cnt; ++i) // cnt是质数个数
    for(int j = 1; j * prime[i] <= n; ++j)
        f[j * prime[i]] += f[j]; // j * prime[i] 在第 i 位上的指数比 j 多 1

类似地,我们还有迪利克雷后缀和\(g(d)=\sum\limits_{d\mid x}f(x)\)

注意区别在于 \(d\mid x\) 还是 \(x\mid d\)。计算方法也是类似的。

for(int i = 1; i <= cnt; ++i) // cnt是质数个数
    for(int j = n / prime[i]; j >= 1; --j)
        f[j] += f[j * prime[i]]; // j 在第 i 位上的指数比 j * prime[i] 少 1

差分

前缀差分:给定 \(g(1),g(2),\dots g(n)\),已知 \(g(d)=\sum\limits_{x\mid d}f(x)\),求 \(f(x)\)\(x\in [1, n]\)

站在高维前缀和/差分的角度,我们只需要将前缀和的那一层循环反向,然后加号变减号即可。

for(int i = 1; i <= cnt; ++i)
    for(int j = n / prime[i]; j >= 1; --j)
        f[j * prime[i]] -= f[j];

后缀差分:给定 \(g(1),g(2),\dots g(n)\),已知 \(g(d)=\sum\limits_{d\mid x}f(x)\),求 \(f(x)\)\(x\in [1, n]\)

for(int i = 1; i <= cnt; ++i)
    for(int j = 1; j * prime[i] <= n; ++j)
        f[j] -= f[j * prime[i]];

例题

ABC361F x=a^b

给定一个正整数 \(n\),求 \(1\) ~ \(n\) 中有多少个数能被写成 \(a^b~(b\ge 2)\) 的形式。

\(n\le 10^{18}\)

这里只写莫比乌斯反演/后缀差分的做法

首先 \(a=1\) 时显然有且仅有 \(x=1\) 符合题意,接下来默认 \(a\ge 2\)

注意到 \(b\) 不会超过 \(59\),所以可以枚举 \(b\)
对于一个 \(b\),有 \(\lfloor \sqrt[b]{n} \rfloor -1\)\(a\) 符合题意。
但是我们不能把 \(\lfloor \sqrt[b]{n} \rfloor -1\) 之和当作答案,因为 \(a_1^{b_1}=a_2^{b_2}\) 的情况会导致算重。

思考一下会发现,同一个数 \(x\) 可能会有多种拆分方式,比如

\[64=4^3=8^2 \]

此时我们希望规定一种方式,使得拆分是唯一的,就不会存在重复了。
所以可以让 \(a\) “最简”,也就是 \(a\) 不能表示为 \(p^q\) 的形式,这时我们可以说 \(x=a^b\) 是“幂次只能是 \(b\) 的数”

那么之前,我们计算的\(\lfloor \sqrt[b]{n} \rfloor -1\)\(a^b\) 就是“幂次只能是 \(kb\) 的数\(~(k\in\Z)\)”。这是因为没有限定 \(a\) 最简,所以 \(a\) 可以继续拆分。

于是我们设 \(f(b)\) 表示 “幂次只能是 \(b\) 的数的个数”,\(g(b)\) 表示“幂次只能是 \(kb\) 的数的个数”,则有下面的关系式:

\[g(b)=\sum\limits_{b\mid x}f(x) \]

我们的目的是求出 \(f\),这种式子有两种处理方式

一:莫比乌斯反演

结论是

\[f(b)=\sum\limits_{b\mid n}\mu(\frac{n}{b})g(n) \]

可以线性筛出 \(\mu(1\) ~ \(n)\),然后 \(O(n\ln{n})\)\(f\)

答案是 \(1+\sum\limits_{i=2}^nf(n)\)

二:高维前缀和

我们可以把一个数进行质因数分解,如 \(n=p_1^{c_1}\cdot p_2^{c_2}\cdot\dots\cdot p_k^{c_k}\)
这样我们就可以认为 \(n\) 是一个有 \(k\) 个维度的向量 \((c_1,c_2,\dots,c_k)\)

对于最初的式子

\[g(b)=\sum\limits_{b\mid x}f(x) \]

这里 \(b\mid x\) 在多维视角下是什么意思呢?
不难发现,\(b\mid x\) 表示 \(x\) 在每一维度下的数值都大于 \(c\)
那么这个式子所反映的关系就是:\(g\)\(f\) 在多维视角下的“后缀和”
所以 \(f\) 就是 \(g\) 的后缀差分

posted @ 2022-10-18 20:18  hzy1  阅读(35)  评论(0编辑  收藏  举报