Cod sursa(job #2180799)

Utilizator Coroian_DavidCoroian David Coroian_David Data 21 martie 2018 10:37:48
Problema Cowfood Scor 58
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.63 kb
#include <bits/stdc++.h>

#define MOD 3210121

#define MAX_N 20
#define MAX_K 30
#define MAX_S 10000

#define MAX_COMB 50

using namespace std;

typedef long long lint;

FILE *f, *g;

int k, s, n;
int total;

lint fact[MAX_S + MAX_K + 1];
int stars[MAX_S + 1];
int a[MAX_N + 1][MAX_K + 1];

void readFile()
{
    f = fopen("cowfood.in", "r");

    fscanf(f, "%d%d%d", &k, &s, &n);

    int i, j;
    for(i = 1; i <= n; i ++)
    {
        for(j = 1; j <= k; j ++)
            fscanf(f, "%d", &a[i][j]);
    }

    fclose(f);
}

void euclid(lint a, lint b, lint &x, lint &y, lint &d)
{
    if(b == 0)
    {
        x = 1;
        y = 0;
        d = a;

        return;
    }

    lint xx, yy, q = a / b;
    euclid(b, a % b, xx, yy, d);

    x = yy;
    y = xx - yy * q;
}

int getStar(int n, int k)
{
    lint up = fact[n + k - 1];
    lint down = fact[n] * fact[k - 1] % MOD;

    lint a, b, d;
    euclid(down, MOD, a, b, d);

    if(a < 0)
        a = a % MOD + MOD;

    lint rez = up * a % MOD;

    return (int)rez;
}

void getStars()
{
    int i;
    stars[0] = 1;
    for(i = 1; i <= s; i ++)
    {
        stars[i] = stars[i - 1] + getStar(i, k);

        if(stars[i] >= MOD)
            stars[i] -= MOD;
    }

    total = stars[s] - (s * k + 1) % MOD;

    if(total < 0)
        total += MOD;
}

int rez;
int mn[MAX_K + 1];

void getPinex()
{
    int i, j, h;
    for(i = 1; i < (1 << n); i ++)
    {
        for(j = 1; j <= k; j ++)
            mn[j] = -1;

        int sign = 0;
        for(j = 0; j < n; j ++)
        {
            if(((1 << j) & i) != 0)
            {
                sign ++;

                for(h = 1; h <= k; h ++)
                    mn[h] = max(mn[h], a[j + 1][h]);
            }
        }

        int sum = s;
        for(j = 1; j <= k; j ++)
            sum -= mn[j];

        if(sum >= 0)
        {
            if(sign & 1)
                rez += stars[sum];

            else
                rez -= stars[sum];

            if(rez < 0)
                rez += MOD;

            if(rez >= MOD)
                rez -= MOD;
        }
    }

    rez = total - rez;

    if(rez < 0)
        rez += MOD;
}

void getFact()
{
    fact[0] = 1;
    for(int i = 1; i <= MAX_K + MAX_S; i ++)
        fact[i]  = fact[i - 1] * i % MOD;
}

void solve()
{
    getFact();

    getStars();

    getPinex();
}

void printFile()
{
    g = fopen("cowfood.out", "w");

    fprintf(g, "%d\n", rez);

    fclose(g);
}

int main()
{
    readFile();

    solve();

    printFile();

    return 0;
}