Problem p03491 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>
using namespace std;

using i64 = int64_t;

#define rep(i, x, y)                                                           \
  for (i64 i = i64(x), i##_max_for_repmacro = i64(y);                          \
       i < i##_max_for_repmacro; ++i)
#define debug(x) #x << "=" << (x)

#ifdef DEBUG
#define _GLIBCXX_DEBUG
#define print(x) std::cerr << debug(x) << " (L:" << __LINE__ << ")" << std::endl
#else
#define print(x)
#endif

const int inf = 1.01e9;
const i64 inf64 = 4.01e18;
const double eps = 1e-9;

template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
  os << "[";
  for (const auto &v : vec) {
    os << v << ",";
  }
  os << "]";
  return os;
}
class trie {
public:
  trie *next[2];

  trie() { fill(next, next + 2, (trie *)0); }
  void insert(const string &str) { insert(str, 0); }
  bool find(const string &str) { return find(str, 0); }
  void insert(const string &str, const int idx) {
    if (idx == str.size())
      return;
    if (this->next[str[idx] - '0'] == NULL)
      this->next[str[idx] - '0'] = new trie();
    this->next[str[idx] - '0']->insert(str, idx + 1);
  }
  bool find(const string &str, const int idx) {
    if (idx == str.size())
      return true;
    if (this->next[str[idx] - '0'] == NULL)
      return false;
    return this->next[str[idx] - '0']->find(str, idx + 1);
  }
};

void solve() {
  i64 N, L;
  cin >> N >> L;

  trie tr;
  vector<string> s(N);
  rep(i, 0, N) {
    cin >> s[i];
    string tmp;
    rep(j, 0, s[i].size()) {
      tmp += s[i][j];
      tr.insert(tmp);
    }
    tr.insert(s[i]);
  }

  vector<i64> ds;
  queue<pair<trie *, int>> que;
  que.push(make_pair(&tr, 0));
  while (!que.empty()) {
    auto tmp = que.front();
    que.pop();
    auto tr = tmp.first;
    auto d = tmp.second;
    if (!tr->next[0] and !tr->next[1])
      continue;
    if (tr->next[0] and tr->next[1]) {
      que.push(make_pair(tr->next[0], d + 1));
      que.push(make_pair(tr->next[1], d + 1));
    } else if (tr->next[0]) {
      que.push(make_pair(tr->next[0], d + 1));
      ds.push_back(d + 1);
    } else {
      que.push(make_pair(tr->next[1], d + 1));
      ds.push_back(d + 1);
    }
  }

  function<i64(i64)> grundy = [&](i64 d) {
    if (d == 0)
      return i64(0);
    i64 d_ = d, res_ = 1;
    while (d % 2 == 0) {
      d /= 2;
      res_ *= 2;
    }
    return res_;
  };

  i64 g = 0;
  for (auto &d : ds) {
    g ^= grundy(L - d + 1);
  }

  cout << (g ? "Alice" : "Bob") << endl;
}

int main() {
  std::cin.tie(0);
  std::ios::sync_with_stdio(false);
  cout.setf(ios::fixed);
  cout.precision(16);
  solve();
  return 0;
}


Fixed submission:
#include <bits/stdc++.h>
using namespace std;

using i64 = int64_t;

#define rep(i, x, y)                                                           \
  for (i64 i = i64(x), i##_max_for_repmacro = i64(y);                          \
       i < i##_max_for_repmacro; ++i)
#define debug(x) #x << "=" << (x)

#ifdef DEBUG
#define _GLIBCXX_DEBUG
#define print(x) std::cerr << debug(x) << " (L:" << __LINE__ << ")" << std::endl
#else
#define print(x)
#endif

const int inf = 1.01e9;
const i64 inf64 = 4.01e18;
const double eps = 1e-9;

template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
  os << "[";
  for (const auto &v : vec) {
    os << v << ",";
  }
  os << "]";
  return os;
}
class trie {
public:
  trie *next[2];

  trie() { fill(next, next + 2, (trie *)0); }
  void insert(const string &str) { insert(str, 0); }
  bool find(const string &str) { return find(str, 0); }
  void insert(const string &str, const int idx) {
    if (idx == str.size())
      return;
    if (this->next[str[idx] - '0'] == NULL)
      this->next[str[idx] - '0'] = new trie();
    this->next[str[idx] - '0']->insert(str, idx + 1);
  }
  bool find(const string &str, const int idx) {
    if (idx == str.size())
      return true;
    if (this->next[str[idx] - '0'] == NULL)
      return false;
    return this->next[str[idx] - '0']->find(str, idx + 1);
  }
};

void solve() {
  i64 N, L;
  cin >> N >> L;

  trie tr;
  vector<string> s(N);
  rep(i, 0, N) {
    cin >> s[i];
    tr.insert(s[i]);
  }

  vector<i64> ds;
  queue<pair<trie *, int>> que;
  que.push(make_pair(&tr, 0));
  while (!que.empty()) {
    auto tmp = que.front();
    que.pop();
    auto tr = tmp.first;
    auto d = tmp.second;
    if (!tr->next[0] and !tr->next[1])
      continue;
    if (tr->next[0] and tr->next[1]) {
      que.push(make_pair(tr->next[0], d + 1));
      que.push(make_pair(tr->next[1], d + 1));
    } else if (tr->next[0]) {
      que.push(make_pair(tr->next[0], d + 1));
      ds.push_back(d + 1);
    } else {
      que.push(make_pair(tr->next[1], d + 1));
      ds.push_back(d + 1);
    }
  }

  function<i64(i64)> grundy = [&](i64 d) {
    if (d == 0)
      return i64(0);
    i64 d_ = d, res_ = 1;
    while (d % 2 == 0) {
      d /= 2;
      res_ *= 2;
    }
    return res_;
  };

  i64 g = 0;
  for (auto &d : ds) {
    g ^= grundy(L - d + 1);
  }

  cout << (g ? "Alice" : "Bob") << endl;
}

int main() {
  std::cin.tie(0);
  std::ios::sync_with_stdio(false);
  cout.setf(ios::fixed);
  cout.precision(16);
  solve();
  return 0;
}