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

#include <algorithm>
#include <bitset>
#include <cassert>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <fstream>
#include <functional>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;
#define pb push_back
#define pf push_front
typedef long long lint;
typedef complex<double> P;
#define mp make_pair
#define fi first
#define se second
typedef pair<int, int> pint;
#define All(s) s.begin(), s.end()
#define rAll(s) s.rbegin(), s.rend()
#define REP(i, a, b) for (int i = a; i < b; i++)
#define rep(i, n) REP(i, 0, n)
// 問題文および制約はちゃんと確認しよう！
// サイズは10^5じゃなくて2×10^5とかかもしれないし、重要な制約・条件を見落としているかも
// とりあえずサンプルを読んでから解法を考えよう？
lint co[58][58];
lint cal(vector<int> v, int S, int K) {
  int n = v.size();
  lint ret = 0;
  rep(i, (1 << 18)) {
    if ((S | i) > S)
      continue;
    int x = 0, t = 1;
    if (__builtin_popcount(i) % 2 > 0)
      t = -1;
    rep(j, n) {
      if (!(i & v[j]))
        x++;
    }
    rep(j, K + 1) { ret += co[x][j] * t; }
  }
  return ret;
}
int a[58];
int main() {
  memset(co, 0, sizeof(co));
  rep(i, 55) {
    co[i][0] = co[i][i] = 1;
    REP(j, 1, i) co[i][j] = co[i - 1][j] + co[i - 1][j - 1];
  }
  int n, K, S, T, m = 0, x, okm = 0;
  cin >> n >> K >> S >> T;
  rep(j, 18) {
    if ((S & (1 << j)) != (T & (1 << j)))
      okm += (1 << j);
  }
  rep(i, n) {
    cin >> x;
    int f = 0;
    rep(j, 18) {
      if ((x & (1 << j)) && !(T & (1 << j)))
        f = 1;
      if (!(x & (1 << j)) && (S & (1 << j)))
        f = 1;
    }
    if (f < 1) {
      a[m] = x;
      m++;
    }
  }
  // cout<<m<<endl;rep(i,m) cout<<a[i]<<endl;
  lint out = 0;
  rep(i, m) {
    vector<int> v;
    REP(j, i + 1, m) v.pb(a[i] ^ a[j]);
    out += cal(v, S ^ T, K - 1);
  }
  cout << out << endl;
}


Error: TLE

Fixed submission:

#include <algorithm>
#include <bitset>
#include <cassert>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <fstream>
#include <functional>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;
#define pb push_back
#define pf push_front
typedef long long lint;
typedef complex<double> P;
#define mp make_pair
#define fi first
#define se second
typedef pair<int, int> pint;
#define All(s) s.begin(), s.end()
#define rAll(s) s.rbegin(), s.rend()
#define REP(i, a, b) for (int i = a; i < b; i++)
#define rep(i, n) REP(i, 0, n)
// 問題文および制約はちゃんと確認しよう！
// サイズは10^5じゃなくて2×10^5とかかもしれないし、重要な制約・条件を見落としているかも
// とりあえずサンプルを読んでから解法を考えよう？
lint dp[2][58][(1 << 18) + 10];
int a[58];
vector<int> ok;
int main() {
  int n, K, S, T, m = 0, x, okm = 0;
  cin >> n >> K >> S >> T;
  rep(j, 18) {
    if ((S & (1 << j)) != (T & (1 << j)))
      okm += (1 << j);
  }
  rep(i, n) {
    cin >> x;
    int f = 0;
    rep(j, 18) {
      if ((x & (1 << j)) && !(T & (1 << j)))
        f = 1;
      if (!(x & (1 << j)) && (S & (1 << j)))
        f = 1;
    }
    if (f < 1) {
      a[m] = x;
      m++;
    }
  }
  // cout<<m<<endl;rep(i,m) cout<<a[i]<<endl;
  lint out = 0;
  rep(i, m) {
    // cout<<i<<endl;
    // if(i+K>m) continue;
    memset(dp, 0, sizeof(dp));
    dp[1][1][0] = 1;
    REP(j, i + 1, m) {
      // cout<<j<<endl;
      int mask = 0, now = (j - i) % 2, ne = 1 - now;
      memset(dp[ne], 0, sizeof(dp[ne]));
      rep(k, 18) {
        if ((a[j] & (1 << k)) != (a[i] & (1 << k)))
          mask += (1 << k);
      }
      // cout<<j<<endl;
      rep(k, K + 1) rep(l, (1 << 18)) {
        dp[ne][k][l] += dp[now][k][l];
        if (k < K)
          dp[ne][k + 1][(l | mask)] += dp[now][k][l];
      }
    }
    int re = (m - i) % 2;
    REP(j, 1, K + 1) rep(k, (1 << 18)) {
      if ((okm & k) < okm)
        continue;
      out += dp[re][j][k];
    }
  }
  cout << out << endl;
}