Pagini recente » Cod sursa (job #726539) | Cod sursa (job #3349690) | Cod sursa (job #2432669) | Cod sursa (job #1567080) | Cod sursa (job #3338461)
#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 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++) {
int lsb = mask & -mask;
int id = __builtin_ctz(lsb);
int prev = mask ^ lsb;
// rebuild max vector for this mask
if (prev == 0) {
cur = bad[id];
} else {
int p = prev;
int pid = __builtin_ctz(lsb);
for (int j = 0; j < K; j++)
cur[j] = max(cur[j], bad[pid][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;
}