Problem p02649 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <bits/stdc++.h>
#define meow(args...) fprintf(stderr, args)
typedef unsigned long long u64;
const int N = 50;
int n, k, s, t, a[N], cnt;
u64 set[2 * N], com[N + 1][N + 1], ans;
void dfs(int x, int nmust, int nmay, u64 must, u64 may) {
  if (nmust > k)
    return;
  while (x < cnt && (set[x] & must))
    ++x;
  if (x == cnt) {
    int tmp = std::min(k, nmay) - nmust;
    ans += com[nmay - nmust][tmp];
    return;
  }
  u64 cur = set[x] & may;
  if (cur == 0)
    return;
  for (; cur; cur &= cur - 1) {
    int id = __builtin_ctzll(cur);
    dfs(x + 1, nmust + 1, nmay, must | 1llu << id, may);
    --nmay;
    may ^= 1llu << id;
  }
}
void gg() {
  puts("0");
  exit(0);
}
int main() {
  std::random_device dev;
  std::mt19937 rng(dev());
  scanf("%d%d%d%d", &n, &k, &s, &t);
  for (int i = 0; i < n; ++i) {
    scanf("%d", a + i);
    if ((a[i] & s) != s || (a[i] | t) != t) {
      --i;
      --n;
    }
  }
  if (n == 0)
    gg();
  for (int i = 0; i <= n; ++i) {
    com[i][0] = com[i][i] = 1;
    for (int j = 1; j < i; ++j)
      com[i][j] = com[i - 1][j - 1] + com[i - 1][j];
  }
  for (int i = 0; i <= n; ++i) {
    for (int j = 1; j <= i; ++j)
      com[i][j] += com[i][j - 1];
  }
  for (int i = 0; i < 18; ++i) {
    int ss = s >> i & 1, tt = t >> i & 1;
    if (ss != tt) {
      u64 cur = 0;
      for (int j = 0; j < n; ++j) {
        if (~a[j] >> i & 1)
          cur |= 1llu << j;
      }
      set[cnt++] = cur;
      if (!cur)
        gg();
      cur = 0;
      for (int j = 0; j < n; ++j) {
        if (a[j] >> i & 1)
          cur |= 1llu << j;
      }
      set[cnt++] = cur;
      if (!cur)
        gg();
    }
  }
  if (cnt == 0) {
    printf("%lld\\n", com[n][k] - 1);
    return 0;
  }
  dfs(0, 0, n, 0, (1llu << n) - 1);
  printf("%llu\\n", ans);
  return 0;
}


Error: TLE

Fixed submission:

#include <algorithm>
#include <bitset>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <functional>
#include <iostream>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <string>
#define REP(_i, _a, _n) for (int _i = _a; _i <= _n; ++_i)
#define PER(_i, _a, _n) for (int _i = _n; _i >= _a; --_i)
#define hr putchar(10)
#define pb push_back
#define lc (o << 1)
#define rc (lc | 1)
#define mid ((l + r) >> 1)
#define ls lc, l, mid
#define rs rc, mid + 1, r
#define x first
#define y second
#define io std::ios::sync_with_stdio(false)
#define endl '\\n'
#define DB(_a)                                                                 \\
  ({                                                                           \\
    REP(_i, 1, n) cout << _a[_i] << ',';                                       \\
    hr;                                                                        \\
  })
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int P = 1e9 + 7, INF = 0x3f3f3f3f;
ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
ll qpow(ll a, ll n) {
  ll r = 1 % P;
  for (a %= P; n; a = a * a % P, n >>= 1)
    if (n & 1)
      r = r * a % P;
  return r;
}
ll inv(ll x) { return x <= 1 ? 1 : inv(P % x) * (P - P / x) % P; }
inline int rd() {
  int x = 0;
  char p = getchar();
  while (p < '0' || p > '9')
    p = getchar();
  while (p >= '0' && p <= '9')
    x = x * 10 + p - '0', p = getchar();
  return x;
}
// head

#ifdef __APPLE__
const int N = 1e2 + 50;
#else
const int N = 1e6 + 50;
#endif

int n, k, ans, a[N], S, T;
map<pair<int, pair<int, int>>, ll> mp;
queue<pair<pair<int, pair<int, int>>, ll>> q;

int main() {
  scanf("%d%d%d%d", &n, &k, &S, &T);
  REP(i, 0, n - 1) {
    scanf("%d", a + i);
    if ((a[i] | T) != T)
      --i, --n;
    else if ((a[i] | S) != a[i])
      --i, --n;
  }
  if (!n)
    return puts("0"), 0;
  ll x = a[0], y = a[0];
  REP(i, 1, n - 1) x &= a[i], y |= a[i];
  if (y != T)
    return puts("0"), 0;
  if ((x | S) != S)
    return puts("0"), 0;
  REP(i, 0, n - 1) {
    for (auto &t : mp) {
      pair<int, pair<int, int>> u = t.x;
      u.y.x &= a[i], u.y.y |= a[i];
      if (++u.x <= k)
        q.push({u, t.y});
    }
    while (q.size()) {
      auto t = q.front();
      q.pop();
      mp[t.x] += t.y;
    }
    ++mp[{1, {a[i], a[i]}}];
  }
  ll ans = 0;
  REP(i, 1, k) ans += mp[{i, {S, T}}];
  printf("%lld\\n", ans);
}