Cod sursa(job #3338458)

Utilizator GliggyGligor Andrei Gliggy Data 3 februarie 2026 15:17:13
Problema Cowfood Scor 96
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.09 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];

    // Precompute binomial coefficients C[n][k] for k <= K
    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 limit) -> int {
        if (limit < 0) return 0;
        return C[limit + K][K];
    };

    // Total mixtures with sum <= S
    int total = count_leq_sum(S);

    // Remove mixtures with 0 nonzero components
    total = sub(total, 1);

    // Remove mixtures with exactly 1 nonzero component
    total = sub(total, mul(K, S));

    // Inclusion–exclusion over failed experiments
    int invalid = 0;

    for (int mask = 1; mask < (1 << N); mask++) {
        vector<int> mx(K, 0);

        for (int i = 0; i < N; i++) {
            if (mask & (1 << i)) {
                for (int j = 0; j < K; j++) {
                    mx[j] = max(mx[j], bad[i][j]);
                }
            }
        }

        int sum = 0;
        for (int j = 0; j < K; j++) sum += mx[j];
        if (sum > S) continue;

        int ways = count_leq_sum(S - sum);
        int bits = __builtin_popcount(mask);

        if (bits & 1)
            invalid = add(invalid, ways);
        else
            invalid = sub(invalid, ways);
    }

    int answer = sub(total, invalid);
    cout << answer << "\n";

    return 0;
}