Problem p02649 (C++) — buggy submission, verdict: Runtime Error

#include <bits/stdc++.h>

int ri() {
  int n;
  scanf("%d", &n);
  return n;
}

typedef uint32_t u32;
typedef int64_t s64;

struct Comb {
  std::vector<std::vector<s64>> a;
  Comb(int n) { // O(n^2)
    a.resize(n + 1);
    for (int i = 0; i <= n; i++) {
      a[i].resize(i + 1, 1);
      for (int j = 1; j < i; j++)
        a[i][j] = a[i - 1][j] + a[i - 1][j - 1];
    }
  }
  s64 ncr(int n, int r) {
    assert(n >= 0);
    assert(n <= (int)a.size());
    assert(r >= 0);
    assert(r <= n);
    return a[n][r];
  }
};

int64_t gu(int m, int k, const std::vector<int> &revised) {
  int n = revised.size();
  assert(n <= 25);
  int cnt = 0;
  for (int i = 1; i < 1 << n; i++) {
    u32 tmp0 = 0, tmp1 = ~0;
    for (int j = 0; j < n; j++)
      if (i >> j & 1)
        tmp0 |= revised[j], tmp1 &= revised[j];
    if (__builtin_popcount(i) <= k && tmp0 == (1U << m) - 1 && !tmp1)
      cnt++;
  }
  return cnt;
}
int64_t fast(int m, int k, const std::vector<int> &revised) {
  int n = revised.size();
  k = std::min(k, n);
  int64_t ncrsum[n + 1][n + 1];
  memset(ncrsum, 0, sizeof(ncrsum));
  for (int i = 0; i <= n; i++) {
    ncrsum[i][0] = ncrsum[i][i] = 1;
    for (int j = 1; j < i; j++)
      ncrsum[i][j] = ncrsum[i - 1][j - 1] + ncrsum[i - 1][j];
  }
  for (int i = 0; i <= n; i++)
    for (int j = 0; j < n; j++)
      ncrsum[i][j + 1] += ncrsum[i][j];
  uint64_t res = 0;
  for (int i = 0; i < 1 << m; i++) {
    std::map<int, int> ma;
    for (auto j : revised)
      ma[j & i]++;
    uint64_t cur = 0;
    for (auto j : ma)
      cur += ncrsum[j.second][k] - 1;
    if (__builtin_popcount(i) & 1)
      res -= cur;
    else
      res += cur;
  }
  return res;
}

std::mt19937 rnd;
bool random_check(int m, int n) {
  int k = std::uniform_int_distribution<>(1, n)(rnd);
  std::vector<int> revised(n);
  for (auto &i : revised)
    i = std::uniform_int_distribution<>(0, (1 << m) - 1)(rnd);
  auto r0 = gu(m, k, revised);
  auto r1 = fast(m, k, revised);
  if (r0 != r1) {
    std::cerr << "FAILED" << std::endl;
    std::cerr << m << " " << k << std::endl;
    for (auto i : revised)
      std::cerr << i << " ";
    std::cerr << std::endl;
    std::cerr << r0 << " " << r1 << std::endl;
    return false;
  }
  return true;
}

int main() {
  int n = ri(), k = ri();

  u32 s = ri(); // and
  u32 t = ri(); // or
  if ((s & t) != s) {
    puts("0");
    return 0;
  }
  u32 a[n];
  for (auto &i : a)
    i = ri();

  u32 mask = ~s & t;
  std::vector<int> all;

  std::vector<int> revised;
  for (int i = 0; i < 18; i++)
    if (mask >> i & 1)
      all.push_back(i);
  int m = all.size();
  for (auto i : a) {
    if ((i & s) != s)
      continue;
    if (~t & i)
      continue;
    int cur = 0;
    for (int j = 0; j < (int)all.size(); j++)
      if (i >> all[j] & 1)
        cur |= 1 << j;
    revised.push_back(cur);
  }
  n = revised.size();
  printf("%" PRId64 "\\n",
         revised.size() <= 0 ? gu(m, k, revised) : fast(m, k, revised));

  return 0;
}


Error: 0

Fixed submission:

#include <bits/stdc++.h>

int ri() {
  int n;
  scanf("%d", &n);
  return n;
}

typedef uint32_t u32;
typedef int64_t s64;

struct Comb {
  std::vector<std::vector<s64>> a;
  Comb(int n) { // O(n^2)
    a.resize(n + 1);
    for (int i = 0; i <= n; i++) {
      a[i].resize(i + 1, 1);
      for (int j = 1; j < i; j++)
        a[i][j] = a[i - 1][j] + a[i - 1][j - 1];
    }
  }
  s64 ncr(int n, int r) {
    assert(n >= 0);
    assert(n <= (int)a.size());
    assert(r >= 0);
    assert(r <= n);
    return a[n][r];
  }
};

int64_t gu(int m, int k, const std::vector<int> &revised) {
  int n = revised.size();
  assert(n <= 25);
  int cnt = 0;
  for (int i = 1; i < 1 << n; i++) {
    u32 tmp0 = 0, tmp1 = ~0;
    for (int j = 0; j < n; j++)
      if (i >> j & 1)
        tmp0 |= revised[j], tmp1 &= revised[j];
    if (__builtin_popcount(i) <= k && tmp0 == (1U << m) - 1 && !tmp1)
      cnt++;
  }
  return cnt;
}
int64_t fast(int m, int k, const std::vector<int> &revised) {
  assert(revised.size() <= 5);
  for (auto i : revised)
    assert(0 <= i && i < 1 << m);
  int n = revised.size();
  int64_t ncrsum[n + 1][n + 1];
  memset(ncrsum, 0, sizeof(ncrsum));
  for (int i = 0; i <= n; i++) {
    ncrsum[i][0] = ncrsum[i][i] = 1;
    for (int j = 1; j < i; j++)
      ncrsum[i][j] = ncrsum[i - 1][j - 1] + ncrsum[i - 1][j];
  }
  for (int i = 0; i <= n; i++)
    for (int j = 0; j < n; j++)
      ncrsum[i][j + 1] += ncrsum[i][j];
  uint64_t res = 0;
  for (int i = 0; i < 1 << m; i++) {
    std::map<int, int> ma;
    for (auto j : revised)
      ma[j & i]++;
    uint64_t cur = 0;
    for (auto j : ma)
      cur += ncrsum[j.second][k] - 1;
    if (__builtin_popcount(i) & 1)
      res -= cur;
    else
      res += cur;
  }
  return res;
}

std::mt19937 rnd;
bool random_check(int m, int n) {
  int k = std::uniform_int_distribution<>(1, n)(rnd);
  std::vector<int> revised(n);
  for (auto &i : revised)
    i = std::uniform_int_distribution<>(0, (1 << m) - 1)(rnd);
  auto r0 = gu(m, k, revised);
  auto r1 = fast(m, k, revised);
  if (r0 != r1) {
    std::cerr << "FAILED" << std::endl;
    std::cerr << m << " " << k << std::endl;
    for (auto i : revised)
      std::cerr << i << " ";
    std::cerr << std::endl;
    std::cerr << r0 << " " << r1 << std::endl;
    return false;
  }
  return true;
}

int main() {
  int n = ri(), k = ri();

  u32 s = ri(); // and
  u32 t = ri(); // or
  if ((s & t) != s) {
    puts("0");
    return 0;
  }
  u32 a[n];
  for (auto &i : a)
    i = ri();

  u32 mask = ~s & t;
  std::vector<int> all;

  std::vector<int> revised;
  for (int i = 0; i < 18; i++)
    if (mask >> i & 1)
      all.push_back(i);
  int m = all.size();
  for (auto i : a) {
    if ((i & s) != s)
      continue;
    if (~t & i)
      continue;
    int cur = 0;
    for (int j = 0; j < (int)all.size(); j++)
      if (i >> all[j] & 1)
        cur |= 1 << j;
    revised.push_back(cur);
  }
  n = revised.size();
  printf("%" PRId64 "\\n",
         revised.size() <= 0 ? gu(m, k, revised) : fast(m, k, revised));

  return 0;
}