Cod sursa(job #3166816)

Utilizator Dragono63Stanciu Rares Stefan Dragono63 Data 9 noiembrie 2023 17:30:39
Problema Frac Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.62 kb
#ifndef LOCAL
    #pragma GCC optimize("Ofast")
#endif

#ifdef LOCAL
    #define _GLIBCXX_DEBUG
#endif

#include <bits/stdc++.h>
#define pb push_back
#define pii pair<int, int>
using ll = long long;
using ci = const int;
using cll = const long long;

using namespace std;

const int NMAX = 13;
const int POW_MAX = (1 << NMAX);
/*******************************/
// INPUT / OUTPUT

#ifndef LOCAL
    ifstream in("frac.in");
    ofstream out("frac.out");
    #define cin in
    #define cout out
#endif
/*******************************/
/// GLOBAL DECLARATIONS

ll N, LIM, P;
ll rasp;
ll intersectie[POW_MAX], nr_biti[POW_MAX];

vector <int> div_primi;
/*******************************/
/// FUNCTIONS

void ReadInput();
void Solution();
void Output();
/*******************************/
///-------------------------------------
inline void ReadInput()
{
    cin >> LIM >> P;
}
///-------------------------------------
bool ok(ll lim)
{
    ll rasp = 0;
    int masca_max = (1 << N), semn;
    for (int mask = 1 ; mask < masca_max ; ++ mask)
    {
        semn = 1;
        if (nr_biti[mask] % 2 == 0)
            semn = -1;

        rasp += semn * (lim / intersectie[mask]);
    }

    rasp = lim - rasp;

    return (rasp >= P);
}
///-------------------------------------
inline vector <int> get_prime_divs(ll nr)
{
    ll div = 2;
    vector <int> res;

    while (div * div <= nr)
    {
        if (nr % div == 0)
        {
            res.push_back(div);

            while (nr % div == 0)
                nr /= div;
        }

        ++ div;
    }

    if (nr > 1)
        res.push_back(nr);
    
    return res;
}
///-------------------------------------
inline void Solution()
{
    div_primi = get_prime_divs(LIM);
    N = div_primi.size();
    int masca_max = (1 << N), semn, ultim_bit, cnt_bit;

    nr_biti[0] = 0;
    intersectie[0] = 1;
    for (int mask = 1 ; mask < masca_max ; ++ mask)
    {
        semn = 1;
        ultim_bit = (mask & (-mask));
        cnt_bit = log2(ultim_bit);

        nr_biti[mask] = nr_biti[mask ^ ultim_bit] + 1;
        intersectie[mask] = intersectie[mask ^ ultim_bit] * div_primi[cnt_bit];

        if (nr_biti[mask] % 2 == 0)
            semn = -1;
    }

    ll sol = 0, step = (1LL << 61);

    
    while (step)
    {
        if (!ok(sol + step))
            sol += step;

        step >>= 1;
    }
    

    rasp = sol + 1;
}
///-------------------------------------
inline void Output()
{
    cout << rasp;
}
///-------------------------------------
int main()
{
    #ifndef LOCAL
        ios::sync_with_stdio(false);
        cin.tie(NULL);
        cout.tie(NULL);
    #endif
    ReadInput();
    Solution();
    Output();
    return 0;
}