Cod sursa(job #2080904)

Utilizator anca.sotirAnca Sotir anca.sotir Data 3 decembrie 2017 17:19:34
Problema Frac Scor 50
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.84 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;
    }
}
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 nr_elemente=0;
        long long int produs=1;
        for(long long int i=0; i<=nr_fact_primi-1; ++i)
            {

                long long int aux=((numar&(1<<i))>>i);
                nr_elemente+=aux;
                if(aux)
                    produs*=fact_primi[nr_fact_primi-i];
            }
        if(nr_elemente%2)
            phiX-=x/produs;
        else 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);
    }
}
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;
}