我忽然想起来可以写一个积性函数线性筛。所以我写了一个。
template<typename T, typename F>
vec<T> multiplicative_function_table(u32 n, F &&g)
{
vec<u32> prime;
vec<bool> vis(n + 1);
prime.reserve(n / 15);
vec<T> res(n + 1);
res[1] = T(1);
for (u32 i = 2, t, k, ni; i <= n; i++) {
if (!vis[i]) {
prime.emplace_back(i);
res[i] = g(i, 1);
}
for (u32 j: prime) {
if (i * j > n) break;
vis[i * j] = true;
t = i / j;
if (i == t * j) {
k = 1;
do ni = t, t /= j, k++;
while (ni == t * j);
res[i * j] = res[ni] * g(j, k);
break;
}
res[i * j] = res[i] * g(j, 1);
}
}
return res;
}
传入一个函数(或者仿函数) g
,g(x, y)
返回
这段代码有个比较直觉的地方是,当 i % j == 0
(也就是 i == t * j
)的时候,我直接暴力将
经过打表,我认为这玩意就是对的。我打出的表显示,
这个性质的意义是,线性筛积性函数的限制更松了:若求
打表程序。
相关讨论。
@syp11 大佬指出其实不止