Cod sursa(job #3219767)

Utilizator divadddDavid Curca divaddd Data 1 aprilie 2024 09:16:28
Problema Cowfood Scor 30
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.15 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 = 32;
const int KMAX = 32;
int n,k,s,a[NMAX][KMAX],fact[VMAX],inv[VMAX];
int dp[VMAX],st[KMAX],ans;

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);
}

int cntset = 0;
void bkt(int pas){
    if(pas == n+1){
        if(cntset == 0){
            return;
        }
        int sum = LLONG_MIN;
        for(int i = 1; i <= k; i++){
            int mx = 0;
            for(int j = 1; j <= n; j++){
                if(st[j] == 1){
                    mx = max(mx, a[j][i]);
                }
            }
            sum += mx;
        }
        if(sum > s){
            return;
        }
        if(cntset%2 == 0){
            ans = (ans + dp[s-sum])%MOD;
        }else{
            ans = (ans - dp[s-sum] + MOD)%MOD;
        }
    }else{
        for(int i = 0; i < 2; i++){
            st[pas] = i;
            cntset += i;
            bkt(pas+1);
            cntset -= i;
        }
    }
}

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);
        dp[i] %= MOD;
    }

    ans = dp[s];
    bkt(1);
    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)
**/