std::vector<longlong> pre, suc; std::vector<int> primes; int M; longlong n;
longlongrec(longlong res, int last, longlong mul){ longlong t = (res > M ? suc[n / res] : pre[res]) - pre[primes[last] - 1]; longlong ret = mul * t * 3; for (int i = last, p; i < (int)primes.size(); i++) { p = primes[i]; if ((longlong)p * p > res) break; for (longlong q = p, nrest = res, nmul = mul * 3; q * p <= res; q *= p) { ret += rec(nrest /= p, i + 1, nmul); nmul += mul * 2; ret += nmul; } } return ret; }
inlinelonglongextEratosthenesSieve(constlonglong n){ M = sqrt(n); pre.clear(); suc.clear(); primes.clear(); pre.resize(M + 1); suc.resize(M + 1); for (int i = 1; i <= M; i++) { pre[i] = i - 1; suc[i] = n / i - 1; } for (int p = 2, end; p <= M; p++) { if (pre[p] == pre[p - 1]) continue; primes.push_back(p); constlonglong pcnt = pre[p - 1], q = (longlong)p * p, m = n / p; end = std::min<longlong>(M, n / q); for (int i = 1, w = M / p; i <= w; i++) suc[i] -= suc[i * p] - pcnt; for (int i = M / p + 1; i <= end; i++) suc[i] -= pre[m / i] - pcnt; for (int i = M; i >= q; i--) pre[i] -= pre[i / p] - pcnt; } primes.push_back(M + 1); return n > 1 ? 1 + rec(n, 0, 1) : 1; }
std::vector<longlong> pre, suc; std::vector<int> primes; int M; longlong n;
longlongrec(longlong res, int last, longlong mul){ longlong t = (res > M ? suc[n / res] : pre[res]) - pre[primes[last] - 1]; longlong ret = mul * t * 4; for (int i = last, p; i < (int)primes.size(); i++) { p = primes[i]; if ((longlong)p * p > res) break; for (longlong q = p, nrest = res, nmul = mul * 4; q * p <= res; q *= p) { ret += rec(nrest /= p, i + 1, nmul); nmul += mul * 3; ret += nmul; } } return ret; }
inlinelonglongextEratosthenesSieve(constlonglong n){ M = sqrt(n); pre.clear(); suc.clear(); primes.clear(); pre.resize(M + 1); suc.resize(M + 1); for (int i = 1; i <= M; i++) { pre[i] = i - 1; suc[i] = n / i - 1; } for (int p = 2, end; p <= M; p++) { if (pre[p] == pre[p - 1]) continue; primes.push_back(p); constlonglong pcnt = pre[p - 1], q = (longlong)p * p, m = n / p; end = std::min<longlong>(M, n / q); for (int i = 1, w = M / p; i <= w; i++) suc[i] -= suc[i * p] - pcnt; for (int i = M / p + 1; i <= end; i++) suc[i] -= pre[m / i] - pcnt; for (int i = M; i >= q; i--) pre[i] -= pre[i / p] - pcnt; } primes.push_back(M + 1); return n > 1 ? 1 + rec(n, 0, 1) : 1; }
std::vector<uint64_t> pre, suc; std::vector<int> primes; int M; uint64_t n, k;
uint64_trec(uint64_t res, int last, uint64_t mul){ uint64_t t = (res > M ? suc[n / res] : pre[res]) - pre[primes[last] - 1]; uint64_t ret = mul * t * (k + 1); for (int i = last, p; i < (int)primes.size(); i++) { p = primes[i]; if ((uint64_t)p * p > res) break; for (uint64_t q = p, nrest = res, nmul = mul * (k + 1); q * p <= res; q *= p) { ret += rec(nrest /= p, i + 1, nmul); nmul += mul * k; ret += nmul; } } return ret; }
inlineuint64_textEratosthenesSieve(constuint64_t n){ M = sqrt(n); pre.clear(); suc.clear(); primes.clear(); pre.resize(M + 1); suc.resize(M + 1); for (int i = 1; i <= M; i++) { pre[i] = i - 1; suc[i] = n / i - 1; } for (int p = 2, end; p <= M; p++) { if (pre[p] == pre[p - 1]) continue; primes.push_back(p); constuint64_t pcnt = pre[p - 1], q = (uint64_t)p * p, m = n / p; end = std::min<uint64_t>(M, n / q); for (int i = 1, w = M / p; i <= w; i++) suc[i] -= suc[i * p] - pcnt; for (int i = M / p + 1; i <= end; i++) suc[i] -= pre[m / i] - pcnt; for (int i = M; i >= q; i--) pre[i] -= pre[i / p] - pcnt; } primes.push_back(M + 1); return n > 1 ? 1 + rec(n, 0, 1) : 1; }
intmain(){ std::ios::sync_with_stdio(false); std::cin.tie(NULL); std::cout.tie(NULL); int T; for (std::cin >> T; T--;) { std::cin >> n >> k; std::cout << extEratosthenesSieve(n) << '\n'; } return0; }