Cod sursa(job #2291729)

Utilizator BogdanisarBurcea Bogdan Madalin Bogdanisar Data 28 noiembrie 2018 15:51:59
Problema Cowfood Scor 54
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.1 kb
#include <bits/stdc++.h>

using namespace std;

#if 1
    #define pv(x) std::cout<<#x<<" = "<<(x)<<"; ";std::cout.flush()
    #define pn std::cout<<endl
#else
    #define pv(x)
    #define pn
#endif

#ifdef INFOARENA
    ifstream in("cowfood.in");
    ofstream out("cowfood.out");
#else
    #define in cin
    #define out cout
#endif

using ll = long long;
using ull = unsigned long long;
using uint = unsigned int;
using ld = long double;
using pii = pair<int,int>;
using pll = pair<ll,ll>;
using pld = pair<ld, ld>;
#define pb push_back
const double PI = 3.14159265358979323846264338327950288419716939937510582097494459230781640628620899862;
const int inf_int = 2e9 + 5;
const ll inf_ll = 1e18 + 5;
const int SMax = 1e4 + 5;
const int NMax = 20 + 5;
const int KMax = 30 + 5;
const int mod = 3210121;
const int dx[] = {-1,0,0,+1}, dy[] = {0,-1,+1,0};

int comb[SMax + KMax][KMax], pcomb[SMax + KMax];
int mixture[NMax][KMax];

int main() {
    cin.sync_with_stdio(false);
    cin.tie(0);
    
    int K,S,N;
    in >> K >> S >> N;
    comb[0][0] = 1;
    for (int i = 1; i <= S + K - 1; ++i) {
        comb[i][0] = 1;
        for (int j = 1; j < KMax; ++j) {
            comb[i][j] = (comb[i-1][j] + comb[i-1][j-1]) % mod;
            // out << comb[i][j] << ' '; ////
        }
        pcomb[i] = (pcomb[i-1] + comb[i][K-1]) % mod;
        // pn;
    }

    // for (int i = 1; i <= S + K - 1; ++i) {
    //     pcomb[i] = (pcomb[i-1] + comb[i][K-1]) % mod;
    //     // out << pcomb[i] << ' '; ////
    // }
    // // pn; ////

    for (int i = 1; i <= N; ++i) {
        for (int j = 1; j <= K; ++j) {
            in >> mixture[i][j];
        }
    }

    int numBad = 0;
    int lim = 1<<N;
    for (int mask = 1; mask < lim; ++mask) {
        vector<int> maxs(K + 1);
        for (int m = 1; m <= N; ++m) {
            if ( (mask >> (m-1)) & 1 ) {
                for (int i = 1; i <= K; ++i) {
                    maxs[i] = max(maxs[i], mixture[m][i]);
                }
            }
        }

        int sumQuantity = 0;
        for (int i = 1; i <= K; ++i) {
            sumQuantity += maxs[i];
        }

        int numHere;
        if (sumQuantity > S) {
            numHere = 0;
        }
        else {
            int dif = S - sumQuantity;
            numHere = (pcomb[dif + K - 1] - pcomb[(K - 1) - 1] + mod) % mod;
        }

        if (__builtin_popcount(mask) % 2) {
            numBad = (numBad + numHere) % mod;
        }
        else {
            numBad = (numBad - numHere + mod) % mod;
        }
    }

    int totalMixtures = 0;
    // for (int sum = 2; sum <= S; ++sum) {
    //     totalMixtures += comb[sum + K - 1][K - 1];
    //     totalMixtures %= mod;
    //     totalMixtures = (totalMixtures - K + mod) % mod;
    // }
    totalMixtures = (pcomb[S + K - 1] - pcomb[(2 + K - 1) - 1] + mod) % mod;
    totalMixtures = (totalMixtures - (S - 2 + 1) * K + mod) % mod;
    // pv(totalMixtures);pn; ///

    int goodMixtures = (totalMixtures - numBad + mod) % mod;

    out << goodMixtures << '\n';
    
    return 0;
}