Cod sursa(job #3292581)

Utilizator unomMirel Costel unom Data 8 aprilie 2025 16:59:25
Problema Bile2 Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.6 kb
#include <fstream>

using namespace std;

#define int long long

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

int compara(int a[], int 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(int a[], int b[])
{
    a[0] = b[0];
    for(int i = 1; i<=a[0]; i++)
    {
        a[i] = b[i];
    }
}

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

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

int imparte(int 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(int a[], int 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 inmultestemare(int a[], int b[])
{
    temp[0] = a[0] + b[0] - 1;
    for(int i = 1; i<=temp[0]; i++)
    {
        temp[i] = 0;
    }

    for(int i = 1; i<=a[0]; i++)
    {
        for(int j = 1; j<=b[0]; j++)
        {
            temp[i + j - 1] += a[i] * b[j];
        }
    }

    int t = 0;
    for(int i = 1; i<=temp[0]; i++)
    {
        t += temp[i];
        temp[i] = t % 10;
        t /= 10;
    }

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

    a[0] = temp[0];
    for(int i = 1; i<=a[0]; i++)
    {
        a[i] = temp[i];
    }
}

void comb(int 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

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

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

signed main()
{
    in>>n>>d>>sa>>sb;

    for(int i = sa.size() - 1; i>=0; i--)
    {
        a[0]++;
        a[a[0]] = sa[i] - '0';
    }

    for(int i = sb.size() - 1; i>=0; i--)
    {
        b[0]++;
        b[b[0]] = sb[i] - '0';
    }

    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;
}