Cod sursa(job #2409982)

Utilizator popabogdanPopa Bogdan Ioan popabogdan Data 19 aprilie 2019 16:54:09
Problema Cowfood Scor 18
Compilator cpp-64 Status done
Runda Lista lui wefgef Marime 1.89 kb
#include <bits/stdc++.h>

#define Nmax 20
#define Smax 10000
#define Kmax 30
#define MOD 3210121

using namespace std;

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

int N, K, S;
int A[Nmax][Kmax + 5];
int V[Kmax + 5];
int ans;
int fact[Smax + 55];
int inv[Smax + 55];

int pw(int A, int B)
{
    if(B == 0)
        return 1;
    if(B & 1)
        return 1ll * A * pw(A, B - 1) % MOD;
    int P = pw(A, B / 2);
    return 1ll * P * P % MOD;
}

int cntBits(int conf)
{
    int ret = 0;
    while(conf != 0)
    {
        ret++;
        conf &= conf - 1;
    }
    return ret;
}

int comb(int N, int K)
{
    int ret = 1ll * fact[N] * inv[K] % MOD;
    return 1ll * ret * inv[N - K] % MOD;
}

int CNT(int S)
{
    if(S < 0)
        return 0;
    return comb(K + S, K);
}

int main()
{
    fin >> K >> S >> N;
    for(int i = 0; i < N; i++)
        for(int j = 1; j <= K; j++)
            fin >> A[i][j];
    fact[0] = 1;
    for(int i = 1; i <= K + S; i++)
        fact[i] = 1ll * i * fact[i - 1] % MOD;
    for(int i = 0; i <= K + S; i++)
        inv[i] = pw(fact[i], MOD - 2);
    for(int i = 2; i <= K; i++)
        if(i % 2 == 0)
            ans = (ans + 1ll * comb(K, i) * CNT(S - i) % MOD) % MOD;
        else
            ans = (ans - 1ll * comb(K, i) * CNT(S - i) % MOD) % MOD;
    for(int conf = 1; conf < (1 << N); conf++)
    {
        for(int j = 1; j <= K; j++)
            V[j] = 0;
        for(int bit = 0; bit < N; bit++)
            if(conf & (1 << bit))
                for(int j = 1; j <= K; j++)
                    V[j] = max(V[j], A[bit][j]);
        int newS = S;
        for(int j = 1; j <= K; j++)
            newS -= V[j];
        if(cntBits(conf) % 2 == 0)
            ans = (ans + CNT(newS)) % MOD;
        else
            ans = (ans - CNT(newS) + MOD) % MOD;
    }
    fout << ans << "\n";
    return 0;
}