A unitary divisor of a positive integer \(n\) is a divisor \(d\) of \(n\) such that \(\gcd\left(d,\dfrac{n}{d}\right)=1\).
A bi-unitary divisor of \(n\) is a divisor \(d\) for which 1 is the only unitary divisor
of \(d\) that is also a unitary divisor
of \(\dfrac{n}{d}\).
For example, \(2\) is a bi-unitary
divisor of \(8\), because the unitary
divisors of \(2\) are \(\{1,2\}\), and the unitary divisors of
\(8/2\) are \(\{1,4\}\), with \(1\) being the only unitary divisor in
common.
The bi-unitary divisors of \(240\)
are \(\{1,2,3,5,6,8,10,15,16,24,30,40,48,80,120,240\}\).
Let \(P(n)\) be the product of all
bi-unitary divisors of \(n\). Define
\(Q_k(N)\) as the number of positive
integers \(1 \lt n \leq N\) such that
\(P(n)=n^k\). For example, \(Q_2\left(10^2\right)=51\) and \(Q_6\left(10^6\right)=6189\).
ll N = 1000000000000LL; int K1, K2, R, LIMCB; vector<int> primes; vector<int> small_pi; vector<ll> large_pi; ll ans_sum;
voidinit(ll n) { N = n; R = (int)floor(sqrt((longdouble)N)); small_pi.assign(R + 1, 0); large_pi.assign(R + 1, 0); for (int i = 1; i <= R; i++) { small_pi[i] = i - 1; large_pi[i] = N / i - 1; } for (int p = 2; p <= R; p++) { if (small_pi[p] == small_pi[p - 1]) continue; int sp = small_pi[p - 1]; ll p2 = 1LL * p * p; int end = (int)min((ll)R, N / p2); for (int i = 1; i <= end; i++) { ll d = 1LL * i * p; ll v = (d <= R ? large_pi[(int)d] : small_pi[(int)(N / d)]); large_pi[i] -= (v - sp); } if (p2 <= R) { for (int i = R; i >= (int)p2; i--) { small_pi[i] -= (small_pi[i / p] - sp); } } } }
inline ll pi_count(ll x) { if (x <= 1) return0; if (x >= N) return large_pi[1]; if (x <= R) return small_pi[(int)x]; return large_pi[(int)(N / x)]; }
inlineboolused_has(const vector<int> &used, int p) { for (int q : used) if (q == p) returntrue; returnfalse; }
ll count_sqfree(const vector<int> &used, int last, ll limit, int m) { if (limit <= 1) return0; if (m == 1) { ll res = pi_count(limit) - pi_count(last); if (res <= 0) return0; for (int p : used) { if ((ll)p > last && (ll)p <= limit) res--; } returnmax(0ll, res); } ll res = 0; auto it = upper_bound(primes.begin(), primes.end(), last); for (; it != primes.end(); ++it) { int p = *it; if (1LL * p * p > limit) break; if (used_has(used, p)) continue; res += count_sqfree(used, p, limit / p, m - 1); } return res; }