Cod sursa(job #1580716)

Utilizator lflorin29Florin Laiu lflorin29 Data 26 ianuarie 2016 01:59:41
Problema Cowfood Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.79 kb
#include <bits/stdc++.h>

using namespace std;

const int md = 3210121, SMAX = 1 << 14, KMAX = 32;

int c[SMAX][KMAX], a[KMAX][KMAX];
int part[SMAX][KMAX];
int k, s, n;
int act[KMAX];

void citire() {
    ifstream fin("cowfood.in");
    fin >> k >> s >> n;
    srand(time(0));
    for(int i = 0; i < n; ++i)
        for(int j = 0; j < k; ++j)
         fin>>a[i][j];
}

inline void add(int &a, int b) {
    a += b;
    if(a >= md)
        a %= md;
    else if(a < 0)
    for(; a < 0; a += md);
}

int ways(int suma, int cate) {
    return c[suma + cate - 1][cate - 1];
}

void precalc() {
    for(int i = 0; i < SMAX; ++i)
        c[i][0] = 1;
    for(int i = 1; i < SMAX; ++i)
        for(int j = 1; j < KMAX; ++j)
             add(c[i][j], c[i - 1][j] + c[i - 1][j - 1]);
    for(int i = 0; i < SMAX; ++i)
        for(int j = 1; j < KMAX; ++j)
           part[i][j] = ways(i, j);
    for(int i = 1; i < SMAX; ++i)
        for(int j = 0; j < KMAX; ++j)
            add(part[i][j], part[i - 1][j]);
}

inline int rasp(int snow) {
    if(snow < 0) return 0;
    int Ret = part[snow][k];
    return Ret;
}

int Ret;
void Back(int ult,bool crt,int sum=0, int mask=0){
    if(mask != 0) {
    int now=rasp(s-sum);
    if(crt&1)
        add(Ret,-now);
    else add(Ret, now);
    }

    int old[KMAX];
    memcpy(old,act,sizeof old);
    for(int i=ult+1;i<n;++i){
        int sum = 0;
        for(int j=0;j<k;++j)
            act[j]=max(act[j],a[i][j]), sum += act[j];
        Back(i,crt^1,sum,mask|(1<<i));
        memcpy(act,old,sizeof act);
    }
}

void solve() {
    for(int i = 2; i <= s; ++i)
        add(Ret, ways(i, k) - k);
    Back(-1,0);
    ofstream("cowfood.out") << Ret;
}

int main() {
    citire();
    precalc();
    solve();
}