Cod sursa(job #728863)

Utilizator GheorgheMihaiMihai Gheorghe GheorgheMihai Data 29 martie 2012 01:35:19
Problema Cowfood Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.12 kb
#include <stdio.h>

int n, m, s, sol;
int v[22][31];
long long invers[10052], fact[10052];

const int mod = 3210121;

inline int max (int a, int b) {return a > b ? a : b;}

void precalc (int x)
{
	int i;
	
	fact[0] = 1;
	for (i = 1; i <= x; i ++)
		fact[i] = fact[i - 1] * i % mod;
	invers[x] = 2506026;
	//invers[x] = 1;
	//for (i = 1; i <= mod - 2; i ++)
	//	invers[x] = invers[x] * fact[x] % mod;
	for (i = x - 1; i >= 0; i --)
		invers[i] = invers[i + 1] * (i + 1) % mod;
}

inline int comb (int a, int b)
{
	return (int) (fact[a] * invers[b] % mod * invers[a - b] % mod);
}

void rez ()
{
	int st, i, lim = (1 << n) - 1, j;
	
	for (st = 1; st <= lim; st ++)
	{
		int nr[31] = {0}, suma = 0, semn = 1;
		
		for (i = 0; i < n; i ++)
			if (st & (1 << i))
			{
				for (j = 1; j <= m; j ++)
					nr[j] = max (nr[j], v[i + 1][j]);
				semn *= -1;
			}
		
		for (j = 1; j <= m; j ++)
			suma += nr[j];
		
		if (suma <= s)
		{
			sol = sol + semn * comb (s - suma + m, m);
			while (sol <= 0)
				sol += mod;
			while (sol >= mod)
				sol -= mod;
		}
	}
}

void calc (int semn, int st[])
{
	if (semn == 1)
		semn = -1;
	else
		semn = 1;
	
	int i, suma = 0;
	
	for (i = 1; i <= m; i ++)
		suma += st[i];
	
	if (suma <= s)
		sol = sol + semn * comb (s - suma + m, m);
	while (sol <= 0)
		sol += mod;
	while (sol >= mod)
		sol -= mod;
}

void back (int pas, int nr, int st[])
{
	if (pas == n + 1)
	{
		if (nr)
			calc (nr & 1, st);
		return;
	}
	
	back (pas + 1, nr, st);
	
	int i, aux[31];
	
	for (i = 1; i <= m; i ++)
	{
		aux[i] = st[i];
		st[i] = max (st[i], v[pas][i]);
	}
	
	back (pas + 1, nr + 1, st);
	
	for (i = 1; i <= m; i ++)
		st[i] = aux[i];
}

int main ()
{
	freopen ("cowfood.in", "r", stdin);
	freopen ("cowfood.out", "w", stdout);
	
	scanf ("%d %d %d", &m, &s, &n);
	
	precalc (10050);
	
	int i, j;
	int st[31] = {0};
	
	for (i = 1; i <= n; i ++)
		for (j = 1; j <= m; j ++)
			scanf ("%d", &v[i][j]);
	
	sol = (comb (s + m, m) - s * m - 1 + mod) % mod;
	//rez ();
	
	back (1, 0, st);
	
	printf ("%d\n", sol);
	
	return 0;
}