Cod sursa(job #3225842)

Utilizator livliviLivia Magureanu livlivi Data 19 aprilie 2024 09:54:36
Problema Cowfood Scor 40
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.59 kb
#include <bits/stdc++.h>

using namespace std;

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

const int mod = 3'210'121, kmax = 30, nmax = 20, smax = 12'000;

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

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

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

int lgput(int64_t x, int 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() {
	int N = smax + kmax + nmax;
	fact[0] = 1;

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

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

int comb(int n, int 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 solve() {
	rez = (comb(s + k, k) - 1 - k * s) % mod;
	int cate, semn, sum;

	for(int mask = 1; mask < (1 << n); mask++) {
		for(int j = 0; j < k; j++)
			mx[j] = 1;
		cate = sum = 0;

		for(int i = 0; i < n; i++) {
			if((1 << i)&mask) {
				cate++;
				for(int j = 0; j < k; j++)
					mx[j] = max(mx[j], fail[i][j]);
			}
		}

		semn = ((cate % 2 == 1) ? (-1) : (1));
		for(int i = 0; i < k; i++)
			sum += mx[i];

		rez = (rez + comb(s - sum + k, k) * semn) % mod;
	}
}

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