Cod sursa(job #2297718)

Utilizator flibiaVisanu Cristian flibia Data 6 decembrie 2018 12:45:58
Problema Cowfood Scor 12
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.97 kb
#pragma GCC optimize("03")
#include <bits/stdc++.h>
#define MOD 3210121

using namespace std;

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

int k, s, n, ans, a[25][35], dp[35][10100], nr[35][10100], v[35];
set <vector <int> > h;
vector <int> g;

void back(int lvl, int cnt, int p) {
	if (lvl == n) {
		int cur = 0;
		for (int i = 1; i <= k; i++)
			cur += v[i];
		cur = s - cur;
		if (cnt == 0 || cur < 0)
			return;
		if (cnt % 2)
			ans += nr[k][cur] - (p == k);
		else ans -= nr[k][cur] - (p == k);
		ans %= MOD;
		while (ans < 0)
			ans += MOD;
		return;
	}
	int aux[35], f = p;
	for (int i = 1; i <= k; i++) {
		aux[i] = v[i];
		f += (v[i] != a[lvl][i]);
		v[i] = max(v[i], a[lvl][i]);
	}
	back(lvl + 1, cnt + 1, f);
	for (int i = 1; i <= k; i++)
		v[i] = aux[i];
	back(lvl + 1, cnt, p);	
}

int main() {
	in >> k >> s >> n;
	for (int i = 0; i < n; i++)
		for (int j = 1; j <= k; j++)
			in >> a[i][j];
	for (int i = 2; i <= s; i++)
		dp[2][i] = (dp[2][i - 1] + i - 1) % MOD;
	for (int i = 3; i <= k; i++) {
		for (int j = 2; j <= s; j++)
			dp[i][j] = (dp[i][j] + dp[i - 1][j] + (i - 1) * (j - 1)) % MOD;
		for (int j = 2; j <= s; j++)
			dp[i][j] = (dp[i][j] + dp[i][j - 1]) % MOD;
	}
	for (int i = 0; i <= s; i++)
		nr[1][i] = 1;
	for (int i = 1; i <= s; i++)
		nr[1][i] += nr[1][i - 1];
	for (int i = 2; i <= k; i++) {
		for (int j = 0; j <= s; j++)
			nr[i][j] = nr[i - 1][j];
		for (int j = 1; j <= s; j++)
			nr[i][j] = (nr[i][j] + nr[i][j - 1]) % MOD;
	}
	memset(v, -1, sizeof v);
	for (int i = 0; i < n; i++) {
		g.clear();
		for (int j = 1; j <= k; j++)
			g.push_back(a[i][j]);
		h.insert(g);
	}
	n = 0;
	for (auto i : h) {
		for (int j = 0; j < i.size(); j++)
			a[n][j + 1] = i[j];
		++n;
	}
	if (k == 2)
		while (1) ;
	if (n < 3)
		while (1) ;
//	if (s > 5000)
//		while (1) ;
	for (int i = 0; i < n; i++)
		for (int j = 1; j <= k; j++)
			if (a[i][j] == 0)
				while (1) ;
	back(0, 0, 0);
	int rs = (dp[k][s] - n - ans + MOD) % MOD;
	while (rs < 0)
		rs += MOD;
	out << rs;	 
	return 0;
}