Cod sursa(job #3172164)

Utilizator Dragono63Stanciu Rares Stefan Dragono63 Data 20 noiembrie 2023 11:21:34
Problema Cowfood Scor 86
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.49 kb
#include <bits/stdc++.h>

using namespace std;

const int MOD = 3210121;
const int NMAX = 20;
const int KMAX = 35;
const int SMAX = 10100;
const int MASCA_MAX = (1 << NMAX);
ifstream in("cowfood.in");
ofstream out("cowfood.out");
#define cin in
#define cout out

int K, S, N;
int rasp;
int v[NMAX][KMAX], curr[KMAX];
int sp[SMAX];
int fact[SMAX], inv_fact[SMAX];

inline int put_log(int nr, int put)
{
    int ans = 1;
    while (put)
    {
        if (put & 1)
            ans = (1LL * ans * nr) % MOD;
        
        nr = (1LL * nr * nr) % MOD;
        
        put >>= 1;
    }
    
    return ans;
}

inline int inv_mod(int nr)
{
    return put_log(nr, MOD - 2);
}

inline int comb(int n, int k)
{
    int sus = fact[n];
    int jos = (1LL * inv_fact[k] * inv_fact[n - k]) % MOD;
    
    return (1LL * sus * jos) % MOD;
}

inline void pinex(int alese)
{
    int suma = 0;
    for (int i = 0 ; i < K ; ++ i)
        suma += curr[i];
    
    /*
    cout << alese << "\n";
    for (int i = 0 ; i < K ; ++ i)
        cout <<  curr[i] << " ";
    cout << "\n--------------\n";
    */
    
    if (suma >= S) return;
    
    int semn = 1;
    if (alese & 1)
        semn = -1;
    
    // cout << semn << " " << sp[S - suma] << "\n";
    rasp += semn * sp[S - suma];
    
    if (rasp < 0)
        rasp += MOD;
    
    if (rasp >= MOD)
        rasp -= MOD;
    
    return;
}

inline void bkt(int i, int alese)
{
    if (i == N)
    {
        pinex(alese);
        return;
    }
    
    int tmp[KMAX];
    for (int j = 0 ; j < K ; ++ j)
        tmp[j] = curr[j];
    
    for (int j = 0 ; j < K ; ++ j)
        curr[j] = max(curr[j], v[i][j]);
    
    bkt(i + 1, alese + 1);
    
    for (int j = 0 ; j < K ; ++ j)
        curr[j] = tmp[j];
        
    bkt(i + 1, alese);
}

int main()
{
    cin >> K >> S >> N;
    
    for (int i = 0 ; i < N ; ++ i)
    {
        for (int j = 0 ; j < K ; ++ j)
        {
            cin >> v[i][j];
        }
    }
    
    fact[0] = 1;
    for (int i = 1 ; i <= S + K - 1 ; ++ i)
        fact[i] = (1LL * fact[i - 1] * i) % MOD;
    
    inv_fact[S + K - 1] = inv_mod(fact[S + K - 1]);
    for (int i = S + K - 2 ; i >= 1 ; -- i)
    {
        inv_fact[i] = (1LL * inv_fact[i + 1] * (i + 1)) % MOD;
    }
    
    sp[0] = 1;
    for (int i = 1 ; i <= S ; ++ i)
    {
        sp[i] = (sp[i - 1] + comb(i + K - 1, K - 1)) % MOD;
        // cout << i << " " << sp[i] << "\n";
    }

    bkt(0, 0);
    rasp -= (S * K + 1); 
    while (rasp < 0)
        rasp += MOD;
    
    cout << rasp;
    return 0;
}