Cod sursa(job #2703814)
Utilizator | Data | 9 februarie 2021 12:19:31 | |
---|---|---|---|
Problema | Mins | Scor | 100 |
Compilator | cpp-64 | Status | done |
Runda | Arhiva de probleme | Marime | 7.59 kb |
#include <fstream>
#include <cstdint>
#include <cstddef>
#include <vector>
#include <algorithm>
#include <stdexcept>
typedef std::size_t size_t;
typedef std::uint8_t uint8_t;
typedef std::uint32_t uint32_t;
typedef std::uint64_t uint64_t;
int main (void);
void demo (void);
uint64_t solve (size_t c, size_t d);
void scan_distinct_prime_factors (size_t q);
uint32_t count__non_coprimes (void);
int main (void) {
int status = 17;
try {
demo();
status = 0; }
catch ( ... ) {
status = 5; }
return status;
}
void demo (void) {
std::ifstream is("mins.in");
size_t c = 0;
size_t d = 0;
is >> c >> d;
if (1 <= c && c <= 1000000 && 1 <= d && d <= 1000000) {} else {
throw std::invalid_argument("At least one of c and d is a bad apple."); }
uint64_t const answer = solve(c, d);
std::ofstream os("mins.out");
os << answer << '\n';
}
uint64_t solve(size_t c, size_t d) {
/// Determines the number of y/x fractions,
/// 1 ≤ x ≤ c − 1, 1 ≤ y ≤ d − 1, gcd(y, x) = 1,
/// given integers c and d, 1 ≤ c ≤ 1.000.000, 1 ≤ d ≤ 1.000.000.
if ((1 == c) || (1 == d)) {
return 0; }
if (c > d) {
std::swap(c, d); }
std::vector<uint8_t> size(c, 0);
std::vector<uint32_t> signature(c, 1);
for (size_t p = 2; c > p; ++p) {
if (size[p] == 0) {
for (size_t q = p; c > q; q += p) {
size[q] += 1;
signature[q] *= static_cast<uint32_t>(p); }}}
// There are d − 1 irreducible fractios 1/y, y ← 1 … d − 1.
uint64_t const d0 = d - 1;
uint64_t const c0 = c - 1;
uint64_t total = d0;
// The principle of inclusion-exclusion at work, bulk counting and summing,
// the sizes of the sets A[x][d] = {y ∈ ℤ | 1 ≤ y ≤ d − 1, gcd(x, y) ≠ 1}.
total += (c - 2) * (d - 1);
for (size_t q = 2; c > q; ++q) {
uint8_t s = size[signature[q]];
if (0 != s) {
uint64_t const k = d0 / q;
uint64_t const f = c0 / q;
total = ((s & 1) == 0) ? (total + f * k) : (total - f * k);
size[q] = 0; }}
return total;
}