Cod sursa(job #960576)

Utilizator primulDarie Sergiu primul Data 10 iunie 2013 19:11:53
Problema Cowfood Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.18 kb
#include <cstring>
#include <fstream>
#include <algorithm>
 
using namespace std;
 
const int MOD = 3210121;
 
int K, S, N;
int A[22][32];
int fact[20002], invfact[20002];
int D[10002], E[10002];
int result;
 
int power(int x, int y)
{
    if (y == 0) return 1;
    if (y & 1) return 1LL * x * power(1LL * x * x % MOD, y >> 1) % MOD;
    return power(1LL * x * x % MOD, y >> 1);
}
int COMB(int x, int y)
{
    int resnow = fact[x];
    resnow = 1LL * resnow * invfact[y] % MOD;
    resnow = 1LL * resnow * invfact[x - y] % MOD;
    return resnow;
}
 
int P[32];
void Back(int x, int y)
{
    if (y != 0)
    {
        int sumnow = 0;
        for (int i = 1; i <= K; ++i)
            sumnow += P[i];
 
        if (S - sumnow >= 0)
        {
            if (y & 1)
            {
                result -= D[S - sumnow];
                if (result < 0) result += MOD;
            }
            else
            {
                result += D[S - sumnow];
                if (result >= MOD) result -= MOD;
            }
        }
    }
 
    int aux[32];
    for (int i = x + 1; i <= N; ++i)
    {
        for (int j = 1; j <= K; ++j)
        {
            aux[j] = P[j];
            P[j] = max(P[j], A[i][j]);
        }
        Back(i, y + 1);
        for (int j = 1; j <= K; ++j)
            P[j] = aux[j];
    }
}
 
int main()
{
    ifstream fin("cowfood.in");
    ofstream fout("cowfood.out");
 
    fact[0] = 1;
    invfact[0] = 1;
    for (int i = 1; i <= 20000; ++i)
    {
        fact[i] = 1LL * fact[i - 1] * i % MOD;
        invfact[i] = 1LL * invfact[i - 1] * power(i, MOD - 2) % MOD;
    }
 
    fin >> K >> S >> N;
    for (int i = 1; i <= N; ++i)
        for (int j = 1; j <= K; ++j)
            fin >> A[i][j];
 
    D[0] = 1;
    E[0] = 0;
    for (int i = 1; i <= S; ++i)
    {
        D[i] = D[i - 1] + COMB(i + K - 1, K - 1);
        if (D[i] >= MOD) D[i] -= MOD;
 
        E[i] = E[i - 1] + COMB(i + K - 1, K - 1);
        if (E[i] >= MOD) E[i] -= MOD;
        E[i] -= K;
        if (E[i] < 0) E[i] += MOD;
    }
 
    result = E[S];
    Back(0, 0);
 
    fout << result << '\n';
 
    fin.close();
    fout.close();
}