Cod sursa(job #3246555)

Utilizator alexddAlexandru Dima alexdd Data 3 octombrie 2024 17:06:46
Problema Cowfood Scor 60
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.12 kb
#include<bits/stdc++.h>
using namespace std;
ifstream fin("cowfood.in");
ofstream fout("cowfood.out");
const long long MOD = 3210121;
long long put(long long a, int exp)
{
    if(exp==0)
        return 1;
    if(exp%2==0)
        return put(a*a%MOD,exp/2);
    else
        return put(a*a%MOD,exp/2)*a%MOD;
}
long long fact[20005],invf[20005];
int comb(int x, int y)
{
    if(x<y)
        return 0;
    return fact[x]*invf[y]%MOD*invf[x-y]%MOD;
}
int k,s,n;
int a[21][31];
int mxm[31];
int prec[30][1100000];
signed main()
{
    fact[0]=1;
    for(int i=1;i<=20000;i++)
        fact[i] = fact[i-1]*i%MOD;
    invf[20000] = put(fact[20000], MOD-2);
    for(int i=19999;i>=0;i--)
        invf[i] = invf[i+1]*(i+1)%MOD;
    fin>>k>>s>>n;
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<k;j++)
        {
            fin>>a[i][j];
        }
    }
    long long rez=0;
    for(int config=0;config<(1<<n);config++)
    {
        int cnt=0;
        for(int i=0;i<k;i++)
            mxm[i]=0;
        for(int i=0;i<n;i++)
        {
            if(((1<<i)&config))
            {
                cnt++;
                if(cnt==1)
                {
                    for(int j=0;j<k;j++)
                        mxm[j] = max(a[i][j], prec[j][config-(1<<i)]);
                }
            }
        }
        for(int i=0;i<k;i++)
            prec[i][config] = mxm[i];
        int ramase=s,mari=0,mici=0;
        for(int i=0;i<k;i++)
        {
            ramase -= mxm[i];
            if(mxm[i]>0) mari++;
            else mici++;
        }

        if(ramase<0)
            continue;
        int aux;
        if(mari>=2)
        {
            aux = comb(ramase+k,k);
        }
        else if(mari==1)
        {
            aux = (comb(ramase+k,k) - comb(ramase+1,1) + MOD)%MOD;
        }
        else
        {
            assert(mari==0);
            aux = (comb(ramase+k,k) - comb(ramase,1)*k%MOD - 1 + 5*MOD)%MOD;
        }
        if(cnt%2==0)
            rez = (rez + aux)%MOD;
        else
            rez = (rez + MOD - aux)%MOD;
    }
    fout<<rez;
    return 0;
}