Pagini recente » Cod sursa (job #2687197) | Cod sursa (job #3253919) | Cod sursa (job #3138543) | Cod sursa (job #1862784) | Cod sursa (job #3254871)
#include <bits/stdc++.h>
#define int long long
const std :: string FILENAME = "cowfood";
std :: ifstream f (FILENAME + ".in");
std :: ofstream g (FILENAME + ".out");
const int NMAX = 55;
const int mod = 3210121;
int k;
int s;
int n;
long long ret;
int ans[NMAX];
int a[NMAX][NMAX];
int c[NMAX][NMAX];
int sp[NMAX][NMAX];
std :: stack <std :: vector <int>> mems;
void precalc(int n)
{
c[1][0] = c[1][1] = 1;
for(int i = 2; i <= n; i ++)
{
c[i][0] = 1;
for(int j = 1; j <= i; j ++)
{
c[i][j] = (c[i - 1][j - 1] + c[i - 1][j]) % mod;
}
}
for(int i = 1; i <= n; i ++)
{
for(int j = 1; j <= n; j ++)
{
sp[i][j] = (sp[i][j - 1] + c[j][i]) % mod;
}
}
}
void pinex(int cnt, std :: vector <int> aux)//aici se intampla magia
{
int semn = (cnt % 2 == 0) ? -1 : 1;
//cate sunt mai mari decat aux care este o combinatie de unul sau mai multe experimente
//fix S
int sum = 0;
for(int & i : aux)
{
sum += i;
}
int up = s - sum;
if(up < 0)
{
return ;
}
// am stars and bars cu obiecte <= up si cutii = k __ C(up, k), cat timp up >= k
//deci imi trebuie sp dupa k- uri
int _n = up;
_n += k - 1;
int _k = k;
_k --;
ret += semn * sp[_k][_n];
ret += mod;
ret %= mod;
}
void bkt(int poz)
{
if(poz == 1)
{
for(int i = 1; i <= n; i ++)
{
std :: vector <int> aux;
ans[poz] = i;
for(int j = 1; j <= k; j ++)
{
aux.push_back(a[i][j]);
}
pinex(poz, aux);
mems.push(aux);
bkt(poz + 1);
mems.pop();
}
}
else
{
for(int i = ans[poz - 1] + 1; i <= n; i ++)
{
std :: vector <int> aux = mems.top();
ans[poz] = i;
for(int j = 1; j <= k; j ++)
{
aux[j - 1] = std :: max(aux[j - 1], a[i][j]);
}
pinex(poz, aux);
mems.push(aux);
bkt(poz + 1);
mems.pop();
}
}
}
int32_t main()
{
f >> k >> s >> n;
precalc(50);
for(int i = 1; i <= n; i ++)
{
for(int j = 1; j <= k; j ++)
{
f >> a[i][j];
}
}
bkt(1);
int _n = s;
_n += k - 1;
int _k = k;
_k --;
g << (1ll * sp[_k][_n] - 1 - k * s - ret) % mod;
return 0;
}