Cod sursa(job #2416719)

Utilizator tziplea_stefanTiplea Stefan tziplea_stefan Data 27 aprilie 2019 22:29:26
Problema Cowfood Scor 100
Compilator cpp-64 Status done
Runda Lista lui wefgef Marime 1.87 kb
#include <fstream>
#include <bitset>

using namespace std;

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

const int DIM=30;
const int VAL=10005;
const int MOD=3210121;

int K, S, N, i, j;
int SUM[VAL], conf, nr0;
int SOL, A, X;
int COMB[VAL+DIM][DIM];
unsigned short int ANS[1 << 20][30], LOG[(1 << 19)+1], nr, v[DIM][DIM];
bitset <1 << 20> ind;

int main()
{
    fin >> K >> S >> N;
    for (i=0; i<N; i++)
    {
        nr0=0;
        for (j=0; j<K; j++)
        {
            fin >> v[i][j];
            if (v[i][j]==0)
                nr0++;
        }
        if (nr0==K)
        {
            fout << 0 << '\n';
            fin.close();
            fout.close();
            return 0;
        }
    }
    COMB[1][0]=COMB[1][1]=1;
    for (i=2; i<=S+K; i++)
    {
        COMB[i][0]=1;
        for (j=1; j<=min(i, K-1); j++)
        {
            COMB[i][j]=COMB[i-1][j-1]+COMB[i-1][j];
            if (COMB[i][j]>=MOD)
                COMB[i][j]-=MOD;
        }
    }
    for (i=1; i<=S; i++)
    {
        SUM[i]=SUM[i-1]+COMB[i+K-1][K-1];
        if (SUM[i]>=MOD)
            SUM[i]-=MOD;
    }
    for (i=0; i<N; i++)
        LOG[(1 << i)]=i;
    for (conf=1; conf<(1 << N); conf++)
    {
        X=conf & (-conf);
        ind[conf]=1-ind[conf-X];
        A=nr0=0;
        for (j=0; j<K; j++)
        {
            nr=v[LOG[X]][j];
            ANS[conf][j]=max(ANS[conf-X][j], nr);
            if (ANS[conf][j]==0)
                nr0++;
            A+=ANS[conf][j];
        }
        if (A>S)
            continue;
        X=SUM[S-A];
        if (nr0>K-2)
            X-=S-A;
        else
            X++;
        if (ind[conf]==1)
            SOL+=X;
        else
            SOL-=X;
        SOL%=MOD;
        if (SOL<0)
            SOL+=MOD;
    }
    SOL=SUM[S]-SOL-K*S;
    SOL%=MOD;
    if (SOL<0)
        SOL+=MOD;
    fout << SOL << '\n';
    fin.close();
    fout.close();
    return 0;
}