Cod sursa(job #2887076)

Utilizator rapidu36Victor Manz rapidu36 Data 8 aprilie 2022 19:36:17
Problema GFact Scor 100
Compilator c-64 Status done
Runda Arhiva de probleme Marime 1.71 kb
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define NDP 9
#define ST 1
#define DR (1LL << 46)

int d[NDP], p[NDP], ndp;
int a, b;

void descompunere(int n)
{
    int a = 2;
    while (a * a <= n)
    {
        if (n % a == 0)
        {
            d[ndp] = a;///al ndp-lea div. prim al lui n este a
            p[ndp] = 0;///puterea la care apare a in desc. lui n
            while (n % a == 0)
            {
                p[ndp]++;
                n /= a;
            }
            ndp++;
        }
        a++;
    }
    if (n != 1)///ultimul divizor prim este valoarea actuala a lui n
    {
        d[ndp] = n;
        p[ndp++] = 1;
    }
}

long long putere_fact(long long n, int d)
{
    ///returneaza puterea maxima la care poate fi ridicat d (prim) a.i. sa divida n!
    long long nr = 0;
    while (n >= d)
    {
        nr += (n /= d);
    }
    return nr;
}

bool se_divide_fact(long long n)
{
    for (int i = 0; i < ndp; i++)
    {
        long long p_fact = putere_fact(n, d[i]);
        if (p_fact < p[i] * b)///n! nu se divide cu d[i] la puterea p[i]*b
        {
            return false;
        }
    }
    return true;
}

int main()
{
    FILE *in, *out;
    in = fopen("gfact.in", "r");
    out = fopen("gfact.out", "w");
    fscanf(in, "%d%d", &a, &b);
    fclose(in);
    descompunere(a);
    long long st = ST, dr = DR, rez = DR + 1;
    while (st <= dr)
    {
        long long m = (st + dr) / 2;
        if (se_divide_fact(m))
        {
            rez = m;
            dr = m - 1;
        }
        else
        {
            st = m + 1;
        }
    }
    fprintf(out, "%lld", rez);
    fclose(out);
    return 0;
}