Cod sursa(job #3295418)

Utilizator iulia_morariuIuli Morariu iulia_morariu Data 5 mai 2025 17:19:06
Problema Cowfood Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.45 kb
#include <algorithm>
#include <iostream>
#include <fstream>
#include <climits>
#include <vector>
#include <stack>
#include <cmath>
// #include <bits/stdc++.h>
#define in  fin
#define out fout

using namespace std;
using ll = long long;
const ll MOD = 3210121;

ifstream fin("cowfood.in");
ofstream fout("cowfood.out");

ll spp[10000 + 1]; // osa fie gen spp[i] = C(0 + k - 1, k - 1) + ... + C(i + k - 1, k - 1)
// ll f[10051], inv[10051];
ll C[10051][31];
int v[21][31];
int n, k, s; 
ll tot;

ll exp_rpd(ll b, ll e){
    ll p = 1;
    while(e){
        if(e % 2) p = (p * b) % MOD;
        b = (b * b) % MOD;
        e /= 2;
    }
    return p;
}

void fa_combinarile(){
    C[0][0] = 1;
    for(int i = 1; i <= s + k - 1; i++){
        C[i][0] = 1;
        for(int j = 1; j <= min(i, k); j++){
            C[i][j] = C[i - 1][j] + C[i - 1][j - 1];
            if(C[i][j] > MOD) C[i][j] -= MOD;
        }
    }
}

vector<int> am;
void backks(int p, int cnt, int maxi[]){ // backshots
    if(p == n){ // am terminat toate

        // cout << "pt am = ";
        // for(const int & x : am) cout << x << " ";
        // cout << "\nmaxi = ";
        // for(int i = 0; i < k; i++) cout << maxi[i] << " ";
        // cout << '\n';
        if(cnt == 0) return;
        int extra = s;
        for(int j = 0; j < k; j++) extra -= maxi[j];

        if(extra < 0) return;

        ll sum = spp[extra];
        if(cnt % 2 == 1) tot -= sum;
        else tot = (tot + sum) % MOD;

        tot = (tot + MOD) % MOD;
        return;
    }

    backks(p + 1, cnt, maxi); // nu adaug pe al meu

    int ini[k];
    for(int i = 0; i < k; i++){
        ini[i] = maxi[i];
        maxi[i] = max(maxi[i], v[p][i]);
    }

    am.push_back(p);
    backks(p + 1, cnt + 1, maxi);
    am.pop_back();

    for(int i = 0; i < k; i++) maxi[i] = ini[i];
}

signed main(){
    ios_base::sync_with_stdio(false);
    in.tie(NULL);

    in >> k >> s >> n;
    for(int i = 0; i < n; i++){
        for(int j = 0; j < k; j++) in >> v[i][j];
    }
    fa_combinarile();

    spp[0] = 1;
    for(int i = 1; i <= s; i++){
        ll c = C[i + k - 1][k - 1];
        // cout << "C( " << i + k - 1 << " , " << k - 1 << " ) = " << c << '\n';
        spp[i] = (spp[i - 1] + c) % MOD;
        tot = (tot + c - k) % MOD;
        // cout << "i = " << i << " C( " << i + k - 1 << " , " << k - 1 << " ) = " << C(i + k - 1, k - 1) << '\n';
    }

    int maxi[k];
    for(int i = 0; i < k; i++) maxi[i] = 0;
    backks(0, 0, maxi);

    out << tot;

    return 0;
}