Cod sursa(job #1766417)

Utilizator killer301Ioan Andrei Nicolae killer301 Data 27 septembrie 2016 22:04:51
Problema Cowfood Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.08 kb
#include <cstdio>
#include <cstring>
#include <algorithm>

typedef long long LL;

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 ans;

int power(int n, int p)
{
    LL x, pow=1;
    x=n;
    for(int i=0;(1<<i)<=p;i++)
    {
        if((1<<i)&p)
            pow = (pow*x) % MOD;
        x=(x*x) % MOD;
    }
    return pow;
}

int comb(int x, int y)
{
    int ans = fact[x];
    ans = 1LL * ans * invfact[y] % MOD;
    ans = 1LL * ans * invfact[x - y] % MOD;
    return ans;
}

int P[32];
void bkt(int x, int y)
{
    if(y!=0)
    {
        int sum = 0;
        for(int i=1; i<=K; i++)
            sum += P[i];
        if(S >= sum)
        {
            if(y & 1)
            {
                ans -= D[S - sum];
                if(ans < 0) ans += MOD;
            }
            else
            {
                ans += D[S - sum];
                if(ans >= MOD) ans -= 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]);
        }
        bkt(i, y + 1);
        for(int j=1; j<=K; j++)
            P[j] = aux[j];
    }
}

int main()
{
    freopen("cowfood.in", "r", stdin);
    freopen("cowfood.out", "w", stdout);
    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;
    }
    scanf("%d%d%d", &K, &S, &N);
    for(int i=1; i<=N; i++)
        for(int j=1; j<=K; j++)
            scanf("%d", &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;
    }
    ans = E[S];
    bkt(0, 0);
    printf("%d\n", ans);
}