Cod sursa(job #2042340)

Utilizator alexpetrescuAlexandru Petrescu alexpetrescu Data 18 octombrie 2017 14:59:07
Problema Bile2 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.43 kb
#include <cstdio>
#include <cstring>

FILE *fin = fopen("bile2.in", "r");
FILE *fout = fopen("bile2.out", "w");

#define MAXN 1000
#define LUNG 50
#define T 27

const int mask = (1 << T) - 1;

int comb[LUNG], a[LUNG], b[LUNG];
int d[2][MAXN + 1][LUNG];
int x[LUNG], y[LUNG];
long long aux[LUNG];

inline void impart(int v[], int x) {
    long long tr = 0;
    for (int i = v[0]; i > 0; i--) {
        tr <<= T;
        tr += v[i];
        v[i] = tr / x;
        tr %= x;
    }
    while (v[v[0]] == 0)
        v[0]--;
}

inline void inmult(int a[], int b[], int c[]) {
    memset(c, 0, sizeof(int) * (c[0] + 1));
    for (int i = 1; i <= a[0]; i++)
        for (int j = 1; j <= b[0]; j++)
            aux[i + j - 1] += 1LL * a[i] * b[j];
    aux[0] = a[0] + b[0] - 1;
    int i = 1;
    long long tr = 0;
    while (i <= aux[0] || tr) {
        tr += aux[i];
        c[i] = tr & mask;
        tr >>= T;
        aux[i] = 0;
        i++;
    }
    aux[0] = 0;
    c[0] = i - 1;
    while (c[0] > 0 && c[c[0]] == 0)
        c[0]--;
}

inline void inmult(int v[], int x) {
    int i = 1;
    long long tr = 0;
    while (i <= v[0] || tr) {
        tr += 1LL * v[i] * x;
        v[i] = tr & mask;
        tr >>= T;
        i++;
    }
    i--;
    if (i > v[0])
        v[0] = i;
}

inline void adun(int v[], int u[]) {
    int i = 1, tr = 0;
    while (i <= u[0] || tr) {
        tr += v[i] + u[i];
        v[i] = tr & mask;
        tr >>= T;
        i++;
    }
    i--;
    if (i > v[0])
        v[0] = i;
}

inline void adun(int v[], int x) {
    int i = 1;
    while (x) {
        x += v[i];
        v[i] = x & mask;
        x >>= T;
        i++;
    }
    i--;
    if (i > v[0])
        v[0] = i;
}

inline void scadere(int v[], int u[]) {
    int i = 1, tr = 0;
    while (i <= v[0]) {
        tr += v[i] - u[i];
        if (tr < 0) {
            u[i] = tr + mask + 1;
            tr = -1;
        } else {
            u[i] = tr;
            tr = 0;
        }
        i++;
    }
    u[0] = i - 1;
    while (u[0] > 0 && u[u[0]] == 0)
        u[0]--;
}

inline void citire(int v[]) {
    char ch = fgetc(fin);
    while (ch != '\n') {
        inmult(v, 10);
        adun(v, ch - '0');
        ch = fgetc(fin);
    }
}

inline bool cmp() {
    if (x[0] != y[0]) return x[0] > y[0];
    int p = x[0];
    while (p && x[p] == y[p])
        p--;
    return x[p] > y[p];
}

inline bool check(int v[]) {
    inmult(v, b, x);
    inmult(comb, a, y);
    return cmp();
}

int main() {
    int n, e;
    fscanf(fin, "%d%d ", &n, &e);
    e++;

    citire(a);
    citire(b);
    scadere(b, a);

    int k = 1;
    comb[0] = 1;
    comb[1] = n;
    for (int i = 1; i <= n; i++)
        d[1][i][0] = 1, d[1][i][1] = i;

    while (check(d[k % 2][n])) {
        inmult(comb, n - k);
        k++;
        impart(comb, k);

        memset(d[k % 2][k - 1], 0, sizeof(int) * (d[k % 2][k - 1][0] + 1));
        memset(d[k % 2][k - 2], 0, sizeof(int) * (d[k % 2][k - 2][0] + 1));
        for (int i = k; i <= n; i++) {
            memset(d[k % 2][i], 0, sizeof(int) * (d[k % 2][i][0] + 1));
            memcpy(d[k % 2][i], d[k % 2][i - 1], sizeof(int) * (d[k % 2][i - 1][0] + 1));
            if (i - e >= k - 1)
                adun(d[k % 2][i], d[(k - 1) % 2][i - e]);
        }
    }

    fprintf(fout, "%d\n", k);

    fclose(fin);
    fclose(fout);
    return 0;
}