Lemma

Let .

Du’s Second Division Sieve is an algorithm that computes and for multiplicative functions and , if , , , and are given, in time and space.

Algorithm

Lemma

  1. For each in , find .

  2. Use the results from Step 1 to find .

  3. Use the results from Step 2 to find .

  4. For each in , apply the lemma to find .

std::unordered_map<int, int> du(int n, const std::unordered_map<int, int> &sg, const std::unordered_map<int, int> &sh) {
	int m = std::pow(n, .67);
 
	std::vector<int> f(m);
	f[1] = 1;
	for (int i = 2; i < m; i++) {
		if (pk[i] == i) {
			f[i] = sh.at(i) - sh.at(i - 1);
			for (int j = i / pf[i]; j; j /= pf[i]) {
				f[i] -= f[j] * (sg.at(i / j) - sg.at(i / j - 1));
			}
		} else {
			f[i] = f[i / pk[i]] * f[pk[i]];
		}
	}
 
	std::unordered_map<int, int> sf;
	sf[1] = f[1];
	for (int i = 1; i < m; i++) {
		sf[i] = sf[i - 1] + f[i];
	}
	for (int i = n / m; i > 0; i--) {
		sf[n / i] = sh.at(n / i);
		for (int j = 2; j <= n / i; j = n / i / (n / i / j) + 1) {
			sf[n / i] -= (sg.at(n / i / (n / i / j)) - sg.at(j - 1)) * sf[n / i / j];
		}
	}
	return sf;
}