Cod sursa(job #3224746)

Utilizator unomMirel Costel unom Data 16 aprilie 2024 08:32:52
Problema Cowfood Scor 18
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.5 kb
#include <fstream>

using namespace std;

#define int long long

ifstream in("cowfood.in");
ofstream out("cowfood.out");
int k, s, n;
int proaste, toate, ans;
int v[25][40];
int temp[40];
int fact[11005];
int invfact[11005];
int MOD = 3210121;

int starsandbars(int n, int k)
{
    int ans = (fact[n + k - 1] * invfact[k - 1]) % MOD;
    ans = (ans * invfact[n]) % MOD;

    return ans;
}

int lgput(int x, int e)
{
    int ans = 1;

    while(e != 0)
    {
        if(e % 2 == 1)
        {
            ans = (ans * x) % MOD;
        }

        x = (x * x) % MOD;
        e /= 2;
    }

    return ans;
}

signed main()
{
    in>>k>>s>>n;

    fact[0] = invfact[0] = 1;
    for(int i = 1; i<=11000; i++)
    {
        fact[i] = (fact[i - 1] * i) % MOD;
        //invfact[i] = lgput(fact[i], MOD - 2);
    }

    invfact[11000] = lgput(fact[11000], MOD - 2);
    for(int i = 10999; i>=1; i--)
    {
        invfact[i] = (invfact[i + 1] * (i + 1)) % MOD;
    }

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

    int stmax = (1 << n);
    for(int mask = 1; mask < stmax; mask++)
    {
        for(int i = 1; i<=k; i++)
        {
            temp[i] = 0;
        }

        int nr = 0;
        for(int i = 0; i<n; i++)
        {
            if(mask & (1 << i))
            {
                nr++;

                for(int j = 1; j<=k; j++)
                {
                    temp[j] = max(temp[j], v[i][j]);
                }
            }
        }

        /*out<<nr<<" -> ";
        for(int i = 1; i<=k; i++)
        {
            out<<temp[i]<<" ";
        }
        out<<'\n';*/

        int ramase = 0;
        for(int i = 1; i<=k; i++)
        {
            ramase += temp[i];
        }
        ramase = s - ramase;

        if(ramase < 0)
        {
            continue;
        }

        if(nr % 2 == 1)
        {
            proaste = (proaste + starsandbars(ramase, k + 1)) % MOD;

            //out<<starsandbars(ramase, k + 1)<<'\n';
        }
        else
        {
            proaste = (proaste - starsandbars(ramase, k + 1)) % MOD;

            while(proaste < 0)
            {
                proaste += MOD;
            }
        }
    }

    toate = starsandbars(s - k, k + 1);

    //out<<toate<<'\n';

    ans = (toate - proaste) % MOD;
    while(ans < 0)
    {
        ans += MOD;
    }

    out<<ans;

    return 0;
}