Cod sursa(job #2843744)

Utilizator indraznet09Surugiu Dragos indraznet09 Data 2 februarie 2022 21:04:18
Problema Frac Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.48 kb
#include<iostream>
#include<vector>
#include<cmath>
#include<fstream>
#include<algorithm>

#define ll long long

std::vector<ll> decompose(ll x) {
    std::vector<ll> temp;

    while( x > 0 && x % 2 == 0) {
        temp.push_back(2);
        x /= 2;
    }

    for(int i = 3 ; i <= sqrt(x); i += 2) {
        while(x % i == 0) {
            temp.push_back(i);
            x  /= i;
        }
    }

    if(x > 2)
        temp.push_back(x);

    return temp;
}

ll calc_irreductibile_frac(const std::vector<ll>& decomposed, const ll& n, const ll& p, const ll& proposed_value) {
    ll count = 0;
    std::vector<ll> unique = decomposed;
    auto it = std::unique(unique.begin(), unique.end());
    unique.resize(distance(unique.begin(), it));

    for(const auto& x: unique) {
        // std::cout << x << " ";
        ll sum_x = x;
        while(sum_x <= proposed_value ) {
            count++;
            sum_x += x;
        }
    }
    
    // std::cout << "\nCount dupa adunare: " << count << "\n"; 

    for(size_t i = 0 ; i < unique.size() - 1 ; ++i) {
        ll temp_product = unique[i];
        for(size_t j = i + 1; j < unique.size(); ++j) {
            temp_product *= unique[j];
            // std::cout << "Eu sunt temp_product: " << temp_product << "\n";
            ll sum_product = temp_product;
            while(sum_product <= proposed_value) {
                count--;
                sum_product += temp_product;
            }
        }
    }

    // std::cout << "Count dupa scadere: " << count << "\n"; 
    // std::cout << "Eu sunt (proposed_value - count) = " << (proposed_value - count) << "\n";
    return (proposed_value - count);
}


int main() {

    ll n, p;

    std::ifstream in("frac.in");
    std::ofstream  out("frac.out");

    in >> n >> p;

    ll left = 0, right = (1LL << 10), mid, best = -2;

    while(left <= right) {
        mid = left + (right - left) / 2;
        // std::cout << "Eu sunt mid: " << mid << "\n";
        ll val = calc_irreductibile_frac(decompose(n), n, p, mid);
        // std::cout << "Eu sunt val: " << val << "\n";
        // std::cout << "\n\n";
 
        if(val >= p) {
            if(val == p && std::__gcd(mid, n) == 1) {
                best = mid;
            }
            right = mid - 1;
        }
        else {
            left = mid + 1;
        }
    }

    // std:: cout << best << "\n";
    out << best << "\n";

    in.close();
    out.close();
    return 0;
}