Cod sursa(job #1012763)

Utilizator alex_HarryBabalau Alexandru alex_Harry Data 19 octombrie 2013 16:44:13
Problema Frac Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.69 kb
#include <fstream>
#include <vector>
using namespace std;
ifstream f("frac.in");
ofstream g("frac.out");
int M;
int Prime[150000],ind;
bool OK[150000];
long long N,Ord,A,B,Sol,P[150000];
int X[150000];
vector <int> Div;
void Eratostene()
{
    int i,j;
    for(i=2;i<=150000;i++)
    {
       if(OK[i]==0)
       {
           Prime[++ind]=i;
           for(j=i+i;j<=150000;j+=i)
              OK[j]=1;
       }

    }
}
void Divs()
{
    int i=1;
    while(Prime[i]*Prime[i]<=B && Prime[i]!=0)
    {
        if(Prime[i]!=0 && B%Prime[i]==0)
            Div.push_back(Prime[i]);
        while(B%Prime[i]==0 && Prime[i]!=0)
            B/=Prime[i];
        ++i;
    }
    if(B!=1 && B!=0)
        Div.push_back(B);
}
void Back(int k)
{
    for(int i=X[k-1]+1;i<Div.size();i++)
    {
        X[k]=i;
        P[k]=P[k-1]*Div[X[k]];
        if(k%2==0)
            Sol-=A/P[k];
        else
            Sol+=A/P[k];
        if(k<Div.size())
            Back(k+1);
    }
}
unsigned long long power(unsigned long long x,unsigned long long y)
{
    unsigned long long i,p=1;
    for(i=1;i<=y;i++)
        p*=x;
    return p;
}
void Binary_Search()
{
    unsigned long long st=1,dr=power(2,61),mid;
    unsigned long long sol=0;
    while(st<=dr)
    {
        mid=(st+dr)/2;
        A=mid;
        B=N;
        Div.clear();
        Sol=0;
        Divs();
        Back(1);
        if(A-Sol<Ord)
            st=mid+1;
        if(A-Sol>Ord)
            dr=mid-1;
        if(A-Sol==Ord)
            sol=mid,dr=mid-1;
    }
    g<<sol<<"\n";
}
int main()
{
    f>>N>>Ord;
    Eratostene();
    P[0]=1;
    X[0]=-1;
    Binary_Search();
    return 0;
}