Cod sursa(job #3292577)

Utilizator unomMirel Costel unom Data 8 aprilie 2025 16:47:06
Problema Bile2 Scor 60
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.86 kb
#include <fstream>

using namespace std;

#define int long long

ifstream in("bile2.in");
ofstream out("bile2.out");
int n, d, a, b;
__int128 total[100005];
__int128 temp[100005];
__int128 bune[100005];

int compara(__int128 a[], __int128 b[])
{
    if(a[0] != b[0])
    {
        if(a[0] > b[0])
        {
            return 1;
        }
        else
        {
            return -1;
        }
    }

    for(int i = a[0]; i>=1; i--)
    {
        if(a[i] > b[i])
        {
            return 1;
        }
        else if(a[i] < b[i])
        {
            return -1;
        }
    }

    return 0;
}

void copiere(__int128 a[], __int128 b[])
{
    a[0] = b[0];
    for(int i = 1; i<=a[0]; i++)
    {
        a[i] = b[i];
    }
}

void inmulteste(__int128 v[], int x)
{
    __int128 t = 0;
    for(int i = 1; i<=v[0]; i++)
    {
        t += (__int128)v[i] * (__int128)x;
        v[i] = (__int128)t % (__int128)10;
        t = (__int128)t / (__int128)10;
    }

    while(t != 0)
    {
        v[0]++;
        v[v[0]] = (__int128)t % (__int128)10;
        t /= (__int128)10;
    }
}

int imparte(__int128 v[], int x)
{
    int r = 0;
    for(int i = v[0]; i>=1; i--)
    {
        r = r * 10 + v[i];
        v[i] = r / x;
        r = r % x;
    }

    while(v[0] >= 2 && v[v[0]] == 0)
    {
        v[0]--;
    }

    return r;
}

void scade(__int128 a[], __int128 b[])
{
    for(int i = 1; i<=b[0]; i++)
    {
        if(a[i] >= b[i])
        {
            a[i] -= b[i];
        }
        else
        {
            int j = i + 1;
            while(a[j] == 0)
            {
                a[j] = 9;
                j++;
            }

            a[j]--;
            a[i] = 10 + a[i] - b[i];
        }
    }

    while(a[0] >= 2 && a[a[0]] == 0)
    {
        a[0]--;
    }
}

void comb(__int128 v[], int n, int k)
{
    for(int i = 1; i<=k; i++)
    {
        inmulteste(v, n - i + 1);
        imparte(v, i);
    }
}

int check(int x)
{
    int last = 1 + (x - 1) * (d + 1);

    if(last >= n)
    {
        return 1; //toate cazurile sunt bune
    }

    total[0] = total[1] = 1;
    comb(total, n, x);

    int obiecte = n - last;
    int cutii = x + 1;

    temp[0] = temp[1] = 1;
    comb(temp, obiecte + cutii - 1, cutii - 1);
    copiere(bune, total);

    scade(bune, temp);

    //b * bune >= a * total

    inmulteste(bune, b);
    inmulteste(total, a);

    return (compara(bune, total) >= 0);
}

signed main()
{
    in>>n>>d>>a>>b;

    int st = 2;
    int dr = n;
    int ans, mij;

    while(st <= dr)
    {
        mij = (st + dr) / 2;

        if(check(mij))
        {
            ans = mij;
            dr = mij - 1;
        }
        else
        {
            st = mij + 1;
        }
    }

    out<<ans;

    return 0;
}