Cod sursa(job #1020827)

Utilizator Adrian1997Radulescu Adrian Adrian1997 Data 2 noiembrie 2013 18:21:28
Problema Frac Scor 70
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.69 kb
#include <fstream>
#include <cmath>
using namespace std;
ifstream f("frac.in");
ofstream g("frac.out");
int n,k,P;
int nrprim[110011];
int prim[110011];
bool viz[113311];
long long sol,mid;

void ciur(){
    for(register int i=2;i<113311;i++){
        if(!viz[i]){
            nrprim[++nrprim[0]]=i;
            for(register int j=i+i;j<=113311;j+=i)
                viz[j]=true;
        }
    }
}

int ver1(){
    int val=sqrt(mid);
    for(register int i=1;i<=k && prim[i]<=val;i++){
        if(!(mid%prim[i]))
            return true;
    }
    return false;
}

void track(int poz,long long prod,int nr){
    if(poz>k){
        sol+=(nr%2==0?1:-1)*(mid/prod);
        return;
    }
    track(poz+1,prod,nr);

    nr++;
    prod*=prim[poz];
    track(poz+1,prod,nr);
    prod/=prim[poz];
    nr--;
}

inline long long ver(){
    sol=0;
    track(1,1,0);
    if(sol==P)
        return 0;
    else
        return sol-P;
}

int main(void){
    register int i,j,val;
    register long long p,u;

    ciur();
    f>>n>>P;
    i=1,val=sqrt(n),u=n;
    while(u!=1 && nrprim[i]<val){
        if(u%nrprim[i]==0){
            prim[++k]=nrprim[i];
            while(u%prim[k]==0)
                u/=prim[k];
        }
        i++;
    }
    if(u!=1)
        prim[++k]=u;

    p=1;
    u=2305843009213693952;
    long long ok;
    while(p<=u){
        mid=p+(u-p)/2;
        ok=ver();
        if(ok==0 && !ver1()){
            //am gasit solutia
            break;
        }
        else{
            if(ok<0)
                p=mid+1;
            else
                u=mid-1;
        }
    }
    g<<mid;
    f.close();
    g.close();
    return 0;
}