Cod sursa(job #3225929)

Utilizator vladdobro07vladdd vladdobro07 Data 19 aprilie 2024 12:59:31
Problema Cowfood Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.79 kb
#include <bits/stdc++.h>

using namespace std;

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

const int64_t mod = 3'210'121, kmax = 30, nmax = 20, smax = 10'000;

vector<int64_t> fact(smax + kmax + nmax + 1), inv(smax + kmax + nmax + 1), fail[nmax + 1], mx(kmax + 1, 0);

int64_t n, k, s, x, rez = 0, cate, semn, sum;

void read() {
	fin >> k >> s >> n;
	for(int64_t i = 0; i < n; i++) {
		for(int64_t j = 0; j < k; j++) {
			fin >> x;
			fail[i].push_back(x);
		}
	}
}

int64_t lgput(int64_t x, int64_t a) {
	int64_t prod = 1;
	while(a) {
		if(a % 2 == 1)
			prod = (prod * x) % mod;
		x = (x * x) % mod;
		a /= 2;
	}
	return prod % mod;
}

void make_fact() {
	int64_t N = smax + kmax + nmax;
	fact[0] = 1;

	for(int64_t i = 1; i <= N; i++)
		fact[i] = ((int64_t)fact[i - 1] * i) % mod;

	inv[N] = lgput(fact[N], mod - 2);
	for(int64_t i = N - 1; i >= 0; i--)
		inv[i] = ((int64_t)inv[i + 1] * (i + 1)) % mod;
}

int64_t comb(int64_t n, int64_t k) {
	if(k > n || n < 0)
		return 0;

	int64_t sus = fact[n];
	int64_t jos = ((int64_t)inv[k] * inv[n - k]) % mod;

	return (sus * jos) % mod;
}

void bct(int64_t bit = 0) {
	vector<int64_t> aux(k + 1);
	if(bit == n) {
		if(cate == 0)
			return;
		sum = 0;
		for(int i = 0; i < k; i++)
			sum += mx[i];

		if(cate % 2 == 1)
			semn = -1;
		else
			semn = 1;

		rez = (rez + comb(s - sum + k, k) * semn) % mod;
		return;
	}
	//bit 1
	aux = mx;
	cate++;

	for(int i = 0; i < k; i++)
		mx[i] = max(mx[i], fail[bit][i]);

	bct(bit + 1);

	mx = aux;
	cate--;
	//bit 0
	bct(bit + 1);
}

void solve() {
	rez = (comb(s + k, k) - 1 - k * s) % mod;
	sum = cate = 0;
	bct();
}

signed main() {
	read();
	make_fact();
	solve();
	if(rez < 0)
		rez += mod;
	fout << rez;
	return 0;
}