Cod sursa(job #118073)

Utilizator dominoMircea Pasoi domino Data 23 decembrie 2007 01:32:29
Problema Bile2 Scor 30
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.7 kb
#include <stdio.h>
#include <string.h>

#define MAX_N 1005
#define MAX_LEN 205
#define BASE 10000
#define FIN "bile2.in"
#define FOUT "bile2.out"
#define ll long long
#define clear(x) memset(x, 0, (x[0]+1)*sizeof(x[0]))
#define copy(x, y) memcpy(x, y, (x[0] > y[0] ? x[0]+1 : y[0]+1)*sizeof(y[0]))

typedef int bigint[MAX_LEN];

int N, D; char a[MAX_LEN], b[MAX_LEN];
bigint A, B, BA, C[2][MAX_N], comb, res, T1, T2;

void parse(char s[], int n[])
{
    int i, j, t;

    for (i = strlen(s)-1; i >= 0; i -= 4)
    {
        for (t = 0, j = i-3; j <= i; ++j)
            if (j >= 0) t = t*10+(s[j]-'0');
        n[++n[0]] = t;
    }
}

void add(int a[], int b[])
{
    int i, t = 0;

    for (i = 1; i <= a[0] || i <= b[0] || t; ++i, t /= BASE)
        a[i] = (t += a[i]+b[i]) % BASE;
    a[0] = i-1;
}

void mul(int a[], int b)
{
    int i, t = 0;

    for (i = 1; i <= a[0] || t; ++i, t /= BASE)
        a[i] = (t += a[i]*b) % BASE;
    a[0] = i-1;
}

void div(int a[], int b)
{
    int i, t = 0;

    for (i = a[0]; i > 0; --i, t %= b)
        a[i] = (t = t*BASE+a[i])/b;
    for (; a[0] > 0 && !a[a[0]]; --a[0]);
}

void mul(int a[], int b[], int c[])
{
    int i, j, t;

    clear(c);
    for (i = 1; i <= a[0]; ++i)
    {
        for (t = 0, j = 1; j <= b[0] || t; ++j, t /= BASE)
            c[i+j-1] = (t += c[i+j-1] + a[i]*b[j]) % BASE;
        if (c[0] < i+j-2) c[0] = i+j-2;
    }
}

void sub(int a[], int b[])
{
    int i, t = 0;

    for (i = 1; i <= a[0]; ++i)
    {
        t = (a[i] -= b[i]+t) < 0;
        a[i] += t*BASE;
    }
    for (; a[0] > 0 && !a[a[0]]; --a[0]);
}

int less(int a[], int b[])
{
    int i;

    if (a[0] != b[0]) return a[0] < b[0];
    for (i = 1; i <= a[0]; ++i)
        if (a[i] != b[i]) return a[i] < b[i];
    return 0;
}

int main(void)
{
    int i, j, crt, prev;

    freopen(FIN, "r", stdin);
    freopen(FOUT, "w", stdout);

    scanf("%d %d %s %s", &N, &D, a, b);

    parse(a, A);
    parse(b, B);
    copy(BA, B);
    sub(BA, A);
    comb[0] = comb[1] = 1;

    for (i = 1; i <= N; ++i)
    {
        clear(res);
        crt = i&1, prev = !crt;
        for (j = 1; j <= N; ++j)
        {
            if (i == 1)
            {
                clear(C[crt][j]);
                C[crt][j][0] = C[crt][j][1] = 1;
            }
            else
                copy(C[crt][j], C[crt][j-1]);
            if (i > 1 && j-D-1 > 0)
               add(C[crt][j], C[prev][j-D-1]);
            add(res, C[crt][j]);
        }
        mul(comb, N-i+1); div(comb, i);
        mul(res, B, T1);
        mul(BA, comb, T2);
        if (less(T1, T2)) break;
    }
    printf("%d\n", i);

    return 0;
}