#include <PiTable.hpp>
#include <primecount.hpp>
#include <primecount-internal.hpp>
#include <primesieve.hpp>
#include <int128_t.hpp>
#include <imath.hpp>
#include <print.hpp>
#include <stdint.h>
#include <algorithm>
using namespace primecount;
namespace {
template <typename T>
T S2_trivial(T x,
int64_t y,
int64_t z,
int64_t c,
int threads)
{
if (y < 2)
return 0;
PiTable pi(y, threads);
int64_t pi_y = pi[y];
int64_t sqrtz = isqrt(z);
int64_t prime_c = nth_prime(c);
int64_t start = std::max(prime_c, sqrtz) + 1;
primesieve::iterator it(start - 1, y);
T sum = 0;
int64_t prime;
while ((prime = it.next_prime()) < y)
{
T pp = (T) prime * prime;
int64_t xpp = (int64_t)(x / pp);
if (xpp <= prime) break;
sum += pi_y - pi[xpp];
}
if (prime < y)
{
T n = (pi[y-1] - pi[prime]) + 1;
T a1 = pi[y] - pi[y-1];
T a2 = pi[y] - pi[prime];
sum += n * (a1 + a2) / 2;
}
return sum;
}
}
namespace primecount {
int64_t S2_trivial(int64_t x,
int64_t y,
int64_t z,
int64_t c,
int threads,
bool is_print)
{
if (is_print)
{
print("");
print("=== S2_trivial(x, y) ===");
print_vars(x, y, c, threads);
}
double time = get_time();
int64_t sum = ::S2_trivial(x, y, z, c, threads);
if (is_print)
print("S2_trivial", sum, time);
return sum;
}
#ifdef HAVE_INT128_T
int128_t S2_trivial(int128_t x,
int64_t y,
int64_t z,
int64_t c,
int threads,
bool is_print)
{
if (is_print)
{
print("");
print("=== S2_trivial(x, y) ===");
print_vars(x, y, c, threads);
}
double time = get_time();
int128_t sum = ::S2_trivial(x, y, z, c, threads);
if (is_print)
print("S2_trivial", sum, time);
return sum;
}
#endif
}