Cod sursa(job #2897769)

Utilizator Alex_tz307Lorintz Alexandru Alex_tz307 Data 4 mai 2022 20:01:31
Problema Cowfood Scor 98
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.02 kb
#include <bits/stdc++.h>

using namespace std;

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

const short kS = 1e4 + 1e3;
const int kN = 20;
const short kK = 30;
const int mod = 3210121;
int f[1 + kS], invf[1 + kS];
unsigned short a[kN][kK], req[1 << kN][kK];

void addSelf(int &x, const int &y) {
  x += y;
  if (x >= mod) {
    x -= mod;
  }
}

int add(int x, const int &y) {
  addSelf(x, y);
  return x;
}

void multSelf(int &x, const int &y) {
  x = (int64_t)x * y % mod;
}

int mult(int x, const int &y) {
  multSelf(x, y);
  return x;
}

int Pow(int x, int n) {
  int ans = 1;
  while (n) {
    if (n & 1) {
      multSelf(ans, x);
    }
    multSelf(x, x);
    n >>= 1;
  }
  return ans;
}

int invers(int x) {
  return Pow(x, mod - 2);
}

int nck(int n, int k) {
  return mult(f[n], mult(invf[k], invf[n - k]));
}

void precalc() {
  f[0] = f[1] = 1;
  for (int i = 2; i <= kS; ++i) {
    f[i] = mult(f[i - 1], i);
  }
  invf[kS] = invers(f[kS]);
  for (int i = kS - 1; i >= 0; --i) {
    invf[i] = mult(invf[i + 1], i + 1);
  }
}

void testCase() {
  int k, s, n;
  fin >> k >> s >> n;
  for (int i = 0; i < n; ++i) {
    for (int j = 0; j < k; ++j) {
      fin >> a[i][j];
    }
  }
  int ans = add(nck(s + k, k), mod - 1 - k * s);
  for (int mask = 1; mask < (1 << n); ++mask) {
    int lsb = mask & -mask, bit = 0;
    while ((1 << bit) < lsb) {
      bit += 1;
    }
    int sum = 0, good = 0;
    for (int i = 0; i < k; ++i) {
      req[mask][i] = max(req[mask ^ lsb][i], a[bit][i]);
      good += (req[mask][i] != 0);
      sum += req[mask][i];
    }
    if (sum <= s && good >= 2) {
      if (__builtin_popcount(mask) % 2 == 1) {
        addSelf(ans, mod - nck(s - sum + k, k));
      } else {
        addSelf(ans, nck(s - sum + k, k));
      }
    }
  }
  fout << ans << '\n';
}

int main() {
  precalc();
  int tests = 1;
  for (int tc = 0; tc < tests; ++tc) {
    testCase();
  }
  fin.close();
  fout.close();
  return 0;
}