Cod sursa(job #1778778)

Utilizator MithrilBratu Andrei Mithril Data 14 octombrie 2016 09:08:32
Problema Frac Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.86 kb
#include <bits/stdc++.h>
#define LIMIT_PRIME 1000000
using namespace std;
ifstream fin("frac.in");
ofstream fout("frac.out");
long long answer;
long long n,p,m,t;
vector<int> prim;
vector<int> fact;
vector<int>::iterator it;

void ciur() {
    vector<bool> marked(LIMIT_PRIME/2+1);
    for(int i=1; ((i*i)<<1)+(i<<1)<=LIMIT_PRIME; i+=1)if(!marked[i]) {
            for(int j=((i*i)<<1)+(i<<1); (j<<1)+1<=LIMIT_PRIME; j+=(i<<1)+1)
                marked[j]=true;
        }
    prim.push_back(2);
    for(int i=1; (i<<1)+1<=LIMIT_PRIME; i+=1)
        if(!marked[i])
            prim.push_back(2*i+1);
    return;
}

void makeFact() {
    fact.push_back(0);
    int d;
    for(it=prim.begin(); n>1&&it!=prim.end(); it+=1) {
        d=*it;
        if (n % d == 0)
        {
            fact.push_back(d);
            while (n % d == 0)
                n /= d;
        }
        if (d > sqrt(n) && n > 1)
        {
            fact.push_back(n);
            n = 1;
        }
    }
    t=fact.size()-1;
}

long long solve() {
    long long sol = m;
    for(int i=1; i<(1<<t); i+=1) {
        long long nr=0,prod=1;
        for(int j=0; j<t; j+=1) {
            if((1<<j)&i) {
                prod = 1LL * prod * fact[j+1];
                nr+=1;
            }
        }
        if(nr%2) nr=-1;
        else nr=1;

        sol = sol + 1LL * nr * m/prod;
    }
    return sol;
}

int main()
{
    fin>>n>>p;
    ciur();
    makeFact();
    long long left0 = 1;
    unsigned long long right0=(1LL<<62);
    long long best = right0;

    while(left0<=right0) {
        m = (left0+right0)/2;
        answer = solve();
        if(answer==p)
        {
            best=m;
            right0=m-1;
        }
        else if(answer<p)
            left0=m+1;
        else
            right0=m-1;
    }
    fout<<best;
    return 0;
}