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

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define ii pair<int, int>
#define app push_back
#define all(a) a.begin(), a.end()
#define bp __builtin_popcountll
#define ll long long
#define mp make_pair
#define f first
#define s second
#define Time (double)clock() / CLOCKS_PER_SEC

const int N = 51, M = 9;
int n, k, S, T;
// S - AND, T - OR

int C[N][N];
int from[N];
int a[N], al[N], ar[N];

struct Rec {
  int S, T;
  bool know[M], want[M];
  int getmask(int *a) {
    int ans = 0;
    for (int i = 0; i < n; ++i) {
      bool ban = 0;
      for (int bit = 0; bit < M; ++bit) {
        if (know[bit] && ((a[i] >> bit) & 1) != want[bit]) {
          ban = 1;
          break;
        }
      }
      if (!ban) {
        ans += 1ll << i;
      }
    }
    return ans;
  }
  int ans = 0;
  void solve(int i, int st, int *a, vector<ii> &s) {
    if (i == M) {
      int mask = getmask(a);
      s.app(mp(mask, st & 1));
      return;
    }

    solve(i + 1, st, a, s);

    if (((T >> i) & 1) && !((S >> i) & 1)) {
      know[i] = 1;
      want[i] = 0;
      solve(i + 1, st + 1, a, s);
      know[i] = 0;

      know[i] = 1;
      want[i] = 1;
      solve(i + 1, st + 1, a, s);
      know[i] = 0;
    }
  }
} d;

signed main() {
#ifdef HOME
  freopen("input.txt", "r", stdin);
#else
#define endl '\\n'
  ios_base::sync_with_stdio(0);
  cin.tie(0);
#endif
  for (int i = 0; i < N; ++i)
    C[i][0] = 1;
  for (int i = 1; i < N; ++i)
    for (int j = 1; j < N; ++j)
      C[i][j] = C[i - 1][j - 1] + C[i - 1][j];

  cin >> n >> k >> S >> T;

  for (int i = 0; i < 18; ++i) {
    if (!((T >> i) & 1) && ((S >> i) & 1)) {
      cout << 0 << endl;
      exit(0);
    }
  }

  for (int i = 1; i <= n; ++i) {
    for (int j = 1; j <= k; ++j) {
      from[i] += C[i][j];
    }
  }

  int ptr = 0;
  for (int i = 0; i < n; ++i) {
    int x;
    cin >> x;
    if ((x & S) == S) {
      if ((x & T) == x) {
        a[ptr++] = x;
      }
    }
  }
  n = ptr;
  for (int i = 0; i < n; ++i) {
    al[i] = a[i] & ((1 << M) - 1);
    ar[i] = a[i] >> M;
  }

  // pair (good, st mod 2)

  memset(d.know, 0, sizeof d.know);
  memset(d.want, 0, sizeof d.want);
  d.S = S & ((1 << M) - 1);
  d.T = T & ((1 << M) - 1);

  vector<ii> s1;
  d.solve(0, 0, al, s1);

  memset(d.know, 0, sizeof d.know);
  memset(d.want, 0, sizeof d.want);
  d.S = S >> M;
  d.T = T >> M;

  vector<ii> s2;
  d.solve(0, 0, ar, s2);

  /*
  for (auto e : s1) {
      cout << e.f << ' ' << e.s << endl;
  }
  */

  int ans = 0;
  for (auto l : s1) {
    for (auto r : s2) {
      int can = l.f & r.f;
      int x = from[bp(can)];
      if (l.s ^ r.s) {
        ans -= x;
      } else {
        ans += x;
      }
    }
  }
  cout << ans << endl;
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define ii pair<int, int>
#define app push_back
#define all(a) a.begin(), a.end()
#define bp __builtin_popcountll
#define ll long long
#define mp make_pair
#define f first
#define s second
#define Time (double)clock() / CLOCKS_PER_SEC

const int N = 51, LG = 18;
int n, k, S, T;
// S - AND, T - OR

int C[N][N];
int from[N];

bool know[LG], want[LG];
int a[N];

bool have() {
  for (int i = 0; i < n; ++i) {
    bool ban = 0;
    for (int bit = 0; bit < LG; ++bit) {
      if (know[bit] && ((a[i] >> bit) & 1) != want[bit]) {
        ban = 1;
        break;
      }
    }
    if (!ban)
      return 1;
  }
  return 0;
}

int get() {
  int ans = 0;
  for (int i = 0; i < n; ++i) {
    bool ban = 0;
    for (int bit = 0; bit < LG; ++bit) {
      if (know[bit] && ((a[i] >> bit) & 1) != want[bit]) {
        ban = 1;
        break;
      }
    }
    ans += !ban;
  }
  return ans;
}

int ans = 0;
void solve(int i, int st) {
  if (!have())
    return;

  if (i == LG) {
    int can = get();
    int x = from[can];
    if (st & 1)
      ans -= x;
    else
      ans += x;
    return;
  }

  solve(i + 1, st);

  if (((T >> i) & 1) && !((S >> i) & 1)) {
    know[i] = 1;
    want[i] = 0;
    solve(i + 1, st + 1);
    know[i] = 0;

    know[i] = 1;
    want[i] = 1;
    solve(i + 1, st + 1);
    know[i] = 0;
  }
}

signed main() {
#ifdef HOME
  freopen("input.txt", "r", stdin);
#else
#define endl '\\n'
  ios_base::sync_with_stdio(0);
  cin.tie(0);
#endif
  for (int i = 0; i < N; ++i)
    C[i][0] = 1;
  for (int i = 1; i < N; ++i)
    for (int j = 1; j < N; ++j)
      C[i][j] = C[i - 1][j - 1] + C[i - 1][j];

  cin >> n >> k >> S >> T;

  for (int i = 0; i < LG; ++i) {
    if (!((T >> i) & 1) && ((S >> i) & 1)) {
      cout << 0 << endl;
      exit(0);
    }
  }

  for (int i = 1; i <= n; ++i) {
    for (int j = 1; j <= k; ++j) {
      from[i] += C[i][j];
    }
  }

  int ptr = 0;
  for (int i = 0; i < n; ++i) {
    int x;
    cin >> x;
    if ((x & S) == S) {
      if ((x & T) == x) {
        a[ptr++] = x;
      }
    }
  }
  n = ptr;

  solve(0, 0);
  cout << ans << endl;
}