Cod sursa(job #3338462)

Utilizator GliggyGligor Andrei Gliggy Data 3 februarie 2026 15:20:32
Problema Cowfood Scor 88
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2 kb
#include <bits/stdc++.h>
using namespace std;

static const int MOD = 3210121;

int add(int a, int b) {
    a += b;
    if (a >= MOD) a -= MOD;
    return a;
}

int sub(int a, int b) {
    a -= b;
    if (a < 0) a += MOD;
    return a;
}

int mul(long long a, long long b) {
    return (int)(a * b % MOD);
}

int main() {
    freopen("cowfood.in", "r", stdin);
    freopen("cowfood.out", "w", stdout);

    int K, S, N;
    cin >> K >> S >> N;

    vector<vector<int>> bad(N, vector<int>(K));
    for (int i = 0; i < N; i++)
        for (int j = 0; j < K; j++)
            cin >> bad[i][j];

    // Binomial coefficients
    int MAXN = S + K;
    vector<vector<int>> C(MAXN + 1, vector<int>(K + 1, 0));
    for (int n = 0; n <= MAXN; n++) {
        C[n][0] = 1;
        for (int k = 1; k <= min(n, K); k++)
            C[n][k] = add(C[n - 1][k - 1], C[n - 1][k]);
    }

    auto count_leq_sum = [&](int lim) {
        if (lim < 0) return 0;
        return C[lim + K][K];
    };

    // Total valid mixtures
    int total = count_leq_sum(S);
    total = sub(total, 1);          // zero vector
    total = sub(total, mul(K, S));  // exactly one nonzero

    int invalid = 0;
    int M = 1 << N;
    vector<int> cur(K);

    for (int mask = 1; mask < M; mask++) {
        fill(cur.begin(), cur.end(), 0);

        // build max-vector from scratch
        for (int i = 0; i < N; i++) {
            if (mask & (1 << i)) {
                for (int j = 0; j < K; j++) {
                    cur[j] = max(cur[j], bad[i][j]);
                }
            }
        }

        int sum = 0;
        for (int j = 0; j < K; j++) {
            sum += cur[j];
            if (sum > S) break;
        }
        if (sum > S) continue;

        int ways = count_leq_sum(S - sum);
        if (__builtin_popcount(mask) & 1)
            invalid = add(invalid, ways);
        else
            invalid = sub(invalid, ways);
    }

    cout << sub(total, invalid) << "\n";
    return 0;
}