Cod sursa(job #2080923)

Utilizator anca.sotirAnca Sotir anca.sotir Data 3 decembrie 2017 17:40:17
Problema Frac Scor 60
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.92 kb
#include <fstream>
using namespace std;
ifstream f("frac.in");
ofstream g("frac.out");
long long int fact_primi[30],nr_fact_primi,N,P;
void descFactPrimi(long long int x)
{
    long long int aux=x;
    if(x%2==0)
        fact_primi[++nr_fact_primi]=2;
    while(x%2==0)
        x/=2;
    for(long long int i=3; i<=aux/2; ++i)
    {
        if(x%i==0)
            fact_primi[++nr_fact_primi]=i;
        while(x%i==0)
            x/=i;
    }
    if(x>1) fact_primi[++nr_fact_primi]=x;
}
long long int phi(long long int x)
{
    ///numar e asociat unei submultimi (~fct caracteristica)
    long long int numar_maxim=1<<nr_fact_primi;
    long long int phiX=0;
    for(long long int numar=0; numar<numar_maxim; ++numar)
    {
        long long int produs=1;
        for(long long int i=0; i<=nr_fact_primi-1; ++i)
            if((numar>>i)&1)
                produs*=(-1)*fact_primi[nr_fact_primi-i];
        phiX+=x/produs;
    }
    return phiX;
}
long long int phiN;
long long int aflaInterval(long long int x)
{
    return (x-1)/phiN+1;
}
long long int caut_bin(long long int st,long long int dr,long long int x)
{
    /*if(st>dr) return -1;
    if(st==dr) return st;
    if(st<dr)
    {
        long long int mij=st+(dr-st)/2;
        long long int phiMij=phi(mij);
        if(phiMij<x)
            return caut_bin(mij+1,dr,x);
        if(phiMij>x)
            return caut_bin(st,mij-1,x);
        return caut_bin(st,mij,x);
    }*/
    while(st<dr)
    {
        long long int mij=st+(dr-st)/2;
        long long int phiMij=phi(mij);
        if(phiMij<x)
            st=mij+1;
        else if(phiMij>x)
            dr=mij-1;
        else
            dr=mij;
    }
    return st;
}
int main()
{
    f>>N>>P;
    descFactPrimi(N);
    phiN=phi(N);
    long long int interval=aflaInterval(P);
    P%=phiN;
    if(P==0)
        P=phiN;
    g<<caut_bin(1,N-1,P)+(interval-1)*N;
    return 0;
}