Cod sursa(job #3223316)

Utilizator vladdobro07vladdd vladdobro07 Data 13 aprilie 2024 04:20:47
Problema Cowfood Scor 4
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.69 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> fail[nmax + 1], fact(smax + kmax + nmax + 3);

int64_t n, k, s, x, rez = 0;

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

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

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

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

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

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

	return (sus * lgput(jos, mod - 2)) % mod;
}

int64_t sc(int64_t masca) {
	vector<int64_t> rez(k, 0);
	int64_t cate = 0;

	for(int64_t i = 0; i < n; i++) {
		if((1 << i)&masca) {
			cate++;
			for(int64_t j = 0; j < k; j++)
				rez[j] = max(rez[j], fail[i][j]);
		}
	}

	int64_t sum = 0, semn = ((cate % 2 == 1) ? (-1) : (1));
//	cout << masca << ": ";
	for(int64_t i = 0; i < k; i++) {
//		cout << rez[i] << " ";
		sum += rez[i];
	}
//	cout << ", " << semn << "\n";

	return semn * comb(s - sum + k + 1, k - 1);
}

void solve() {
	rez = comb(s, k);

	for(int64_t mask = 1; mask < (1 << n); mask++) {
		rez = (rez + sc(mask) + mod) % mod;
//		cout << mask << " -> " << rez << "\n";
	}
}

signed main() {
	read();
	make_fact();
	solve();
	fout << rez;
	return 0;
}