我忽然想起来可以写一个积性函数线性筛。所以我写了一个。
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 大佬指出其实不止