Cod sursa(job #3295667)

Utilizator Nasa1004Ema Nicole Gheorghe Nasa1004 Data 7 mai 2025 17:51:19
Problema Cowfood Scor 22
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.36 kb
#include <fstream>
#include <vector>

using namespace std;
const int NMAX = 20;
const int KMAX = 30;
const int SMAX = 10000;
const int MOD = 3210121;
using ll = long long;

ifstream cin("cowfood.in");
ofstream cout("cowfood.out");

ll logexp(ll a, int n) {
    ll p = 1;
    for(int k = 1; k <= n; k <<= 1) {
        if(n & k)
            p *= a;
        a *= a;
        p %= MOD;
        a %= MOD;
    }
    return p;
}

ll fact[SMAX + KMAX + 2], invmod[SMAX + KMAX + 2];
void init() {
    fact[0] = 1;
    for(int i = 1; i <= SMAX + KMAX; i++)
        fact[i] = (fact[i - 1] * i) % MOD;
    invmod[SMAX + KMAX] = logexp(fact[SMAX + KMAX], MOD - 2);
    for(int i = SMAX + KMAX - 1; i >= 0; i--)
        invmod[i] = (invmod[i + 1] * (i + 1)) % MOD;
}

ll comb(int n, int k) {
    if(n < k)
        return 0;
    if(n == k)
        return 1;
    if(k == 0)
        return 1;
    if(k == 1)
        return n;
    ll a = fact[n];
    ll b = (invmod[k] * invmod[n - k]) % MOD;
    return (a * b) % MOD;
}

int a[NMAX + 2][KMAX + 2];
int curr[KMAX + 2];
int mars[SMAX + 2];
int k, s, n;

void backt(int pos, int cnt, int v[KMAX + 2], int sum) {
    if(pos == n) {
        if(cnt == 0 || sum > s)
            return;
        if(cnt % 2 == 1) {
            mars[0]--;
            mars[s - sum + 1]++;
        }
        else {
            mars[0]++;
            mars[s - sum + 1]--;
        }
        return;
    }
    if(sum > s) ///deja e prea mult, nu ne mai pasa
        return;
    ///C1 - nu luam pos-ul
    backt(pos + 1, cnt, v, sum);
    ///C2 - luam pos-ul
    for(int i = 1; i <= k; i++) {
        if(a[pos][i] > v[i]) {
            sum -= v[i];
            sum += a[pos][i];
            v[i] = a[pos][i];
        }
    }
    if(sum <= s)
        backt(pos + 1, cnt + 1, v, sum);

}

int main() {
    cin >> k >> s >> n;
    for(int i = 0; i < n; i++) ///de la 0, ca mask
        for(int j = 1; j <= k; j++)
            cin >> a[i][j];

    init();
    mars[0]++; ///de cate ori adunam comb --> asta e pt nr TOTAL de comb
    mars[s + 1]--;
    backt(0, 0, curr, 0);

    ll tot = 0;
    for(int i = 0; i <= s; i++) {
        if(i > 0)
            mars[i] += mars[i - 1];
        ll nr = (1LL * mars[i] * comb(i + k - 1, k - 1)) % MOD;
        tot = (tot + nr) % MOD;
        //cout << mars[i] << " ";
    }
    tot = (tot - (s * k + 1)) % MOD;
    if(tot < 0)
        tot += MOD;
    cout << tot;
    return 0;
}