Cod sursa(job #3219739)

Utilizator divadddDavid Curca divaddd Data 1 aprilie 2024 00:47:45
Problema Cowfood Scor 32
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.82 kb
#include <bits/stdc++.h>
#pragma GCC target("avx2")
#define int long long
using namespace std;
const int MOD = 3210121;
const int VMAX = 1e4+2;
const int NMAX = 22;
const int KMAX = 32;
int n,k,s,a[NMAX][KMAX],fact[VMAX],inv[VMAX];
int dp[VMAX];

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

int lgput(int n, int a){
    if(a == 0){
        return 1;
    }else{
        if(a%2 == 0){
            int val = lgput(n, a/2);
            return (val*val)%MOD;
        }else{
            return (n*lgput(n, a-1))%MOD;
        }
    }
}

int comb(int n, int m){
    return ((fact[n] * inv[m])%MOD * inv[n-m])%MOD;
}

int snb(int n, int k){
    return comb(n+k-1, k-1);
}

signed main()
{
    fact[0] = 1;
    for(int i = 1; i < VMAX; i++){
        fact[i] = (i*fact[i-1])%MOD;
    }
    inv[VMAX-1] = lgput(fact[VMAX-1], MOD-2);
    for(int i = VMAX-2; i >= 0; i--){
        inv[i] = (inv[i+1] * (i+1))%MOD;
    }
    fin >> k >> s >> n;
    for(int i = 1; i <= n; i++){
        for(int j = 1; j <= k; j++){
            fin >> a[i][j];
        }
    }

    for(int i = 0; i <= s; i++){
        dp[i] = dp[i-1] + snb(i, k);
    }

    int ans = dp[s];
    for(int i = 1; i < (1<<n); i++){
        int sum = 0;
        for(int j = 1; j <= k; j++){
            int mx = 0;
            for(int p = 0; p < n; p++){
                int bt = (i>>p)&1;
                mx = max(mx, (bt ? a[p+1][j] : 0));
            }
            sum += mx;
        }
        if(sum > s){
            continue;
        }
        int coef = (__builtin_popcount(i)&1 ? -1 : 1);
        ans = (ans + coef * dp[s - sum] + MOD)%MOD;
    }
    ans = (ans - (s*k+1)%MOD + MOD)%MOD;
    fout << ans;
    return 0;
}

/**
sum{comb(n+k-1, k-1) | 0 <= n <= S}

comb([k-1, k+S-1], k-1) = comb(k+S, k)
**/