Let .
Du’s First Division Sieve is an algorithm that computes for arithmetic functions and such that , if and are given, in time and space.
Algorithm
Lemma
Proof
For each in in increasing order, apply the lemma to find .
This algorithm solves in the problem in time and space.
std::unordered_map<int, int> du_div(int n, const std::unordered_map<int, int> &sg, const std::unordered_map<int, int> &sh) {
int m = std::sqrt(n);
std::vector<int> d;
for (int i = 1; i < m; i++) {
if (n / (n / i) == i) {
d.push_back(i);
}
}
for (int i = n / m; i > 0; i--) {
d.push_back(n / i);
}
d.erase(std::ranges::unique(d).begin(), d.end());
std::unordered_map<int, int> sf;
for (int i : d) {
sf[i] = sh.at(i);
for (int j = 2; j <= i; j = i / (i / j) + 1) {
sf[i] -= (sg.at(i / (i / j)) - sg.at(j - 1)) * sf[i / j];
}
sf[i] /= sg.at(1);
}
return sf;
}Proof
Lemma
Proof
Applying the lemma yields that this algorithm solves the problem in
time.
Since
and
it follows that
Therefore,