Cod sursa(job #3197503)

Utilizator Chris_BlackBlaga Cristian Chris_Black Data 26 ianuarie 2024 23:29:02
Problema Cowfood Scor 18
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.84 kb
#include <bits/stdc++.h>
#define FOR(i, a, b) for(int i = a; i <= b; ++i)
#define FORR(i, a, b) for(int i = a; i >= b; --i)
#define ll long long

using namespace std;
const string TASK("cowfood");
ifstream fin(TASK + ".in");
ofstream fout(TASK + ".out");
#define cin fin
#define cout fout

const int K = 31, S = 10009, N = 21, Mod = 3210121;

ll k, s, n, a[N][K], tmp[K];

ll add(ll a, ll b)
{
    ll x = a + b;
    if(x >= Mod)x -= Mod;
    if(x < 0)x += Mod;
    return x;
}
ll mul(ll a, ll b)
{
    return (a * b) % Mod;
}
ll PtLg(ll base, ll exp)
{
    ll ret = 1;
    for(; exp; exp >>= 1, base = mul(base, base))
        if(exp & 1)
            ret = mul(ret, base);
    return ret;
}

ll fact[S], invfact[S], sp[S];
ll comb(ll n, ll k)
{
    if(n < k)return 0;
    return mul(fact[n], mul(invfact[k], invfact[n - k]));
}
void Precalc()
{
    fact[0] = 1;
    FOR(i, 1, S - 1)fact[i] = mul(i, fact[i - 1]);

    invfact[S - 1] = PtLg(fact[S - 1], Mod - 2);
    FORR(i, S - 2, 0)invfact[i] = mul(i + 1, invfact[i + 1]);

    sp[0] = 1;
    FOR(i, 1, S - 1)sp[i] = sp[i - 1] + comb(i + k - 1, k - 1);///stars and bars
}

int main()
{
    cin >> k >> s >> n;
    FOR(i, 1, n)FOR(j, 1, k)cin >> a[i][j];


    Precalc();
    int total = mul(mul(k, mul(k - 1, invfact[2])), sp[s - 2]);



    ll reu = 0;
    for(int mask = 1; mask < (1 << n); ++mask)
    {
        FOR(i, 1, k)tmp[i] = 0;

        for(int i = 0; i < n; ++i)
            if(mask & (1 << i))
                FOR(p, 1, k)
                    tmp[p] = max(tmp[p], a[i + 1][p]);

        ll sum = s;
        FOR(i, 1, k)sum -= tmp[i];
        if(sum < 0)continue;
        if(__builtin_popcount(mask) % 2 == 1)reu = add(reu, sp[sum]);
        else reu = add(reu, -sp[sum]);
    }

    cout << add(total, - reu) << '\n';
    return 0;
}