Pagini recente » Cod sursa (job #1443286) | Cod sursa (job #1227339) | Cod sursa (job #1583297) | Cod sursa (job #577108) | Cod sursa (job #2845384)
#include <iostream>
#include <fstream>
using namespace std;
const int MOD = 3210121,
NMAX = 21,
KMAX = 31,
SMAX = 10001;
int K, S, N, V, E;
int M[NMAX][KMAX], x[NMAX], MAX[NMAX][KMAX], SCOMB[SMAX];
ifstream f("cowfood.in");
ofstream g("cowfood.out");
/**
Algoritmul extins al lui Euclid.
Se determina d=cmmdc(a,b) si doua numere intregi x si y,
astfel incat
a * x + b * y = d.
*/
void EuclidExtins(int a, int b, int& d, int& x, int& y) //Varianta recursiva
{
if (b == 0)
{
x = 1;
y = 1;
d = a;
}
else
{
int x0, y0;
EuclidExtins(b, a % b, d, x0, y0);
x = y0;
y = x0 - (a / b) * y0;
}
}
/**
Se determina inversul modular (modulo MOD) al numarului a,
adica un numar x astfel incat a * x sa fie congruent cu 1,
modulo MOD.
*/
int inversMod(int a)
{
int d, x, y;
EuclidExtins(a, MOD, d, x, y);
x %= MOD;
if (x < 0) x += MOD;
return x;
}
void calcSumComb()
{
long long c = 1;
SCOMB[0] = 1;
for (int i = 1; i <= S; i++)
{
c *= i + K - 1;
c %= MOD;
c *= inversMod(i);
c %= MOD;
SCOMB[i] = SCOMB[i - 1] + c;
SCOMB[i] %= MOD;
}
}
void genSubm(int n, int m)
{
int semn, k = 1, i;
x[1] = 0;
if (m % 2 == 0) semn = -1;
else semn = 1;
while (k > 0)
if (x[k] < n - m + k)
{
x[k]++;
for (i = 1; i <= K; i++)
MAX[k][i] = max(MAX[k - 1][i], M[x[k]][i]);
if (k == m)
{
int sum = 0;
for (i = 1; i <= K; i++)
sum += MAX[m][i];
if (sum <= S)
{
E += MOD + semn * SCOMB[S - sum];
E %= MOD;
}
}
else
{
k++;
x[k] = x[k - 1];
}
}
else
k--;
}
int main()
{
f >> K >> S >> N;
for (int i = 1; i <= N; i++)
for (int j = 1; j <= K; j++)
f >> M[i][j];
calcSumComb();
///E = 0;
for (int i = 1; i <= N; i++)
genSubm(N, i);
V = SCOMB[S] + (MOD - S * K - 1);
V %= MOD;
V += MOD - E;
V %= MOD;
g << V;
f.close();
g.close();
return 0;
}