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

#include <bits/stdc++.h>

#define REP(i, s, n) for (int i = s; i < n; i++)
#define rep(i, n) REP(i, 0, n)

using namespace std;

const int IINF = INT_MAX;

int n, found, len;
vector<string> buf[30], seq;
string tmp, sequence, answer;
char transfer[26];

bool comp(const string &a, const string &b) {
  set<char> A, B;
  rep(i, a.size()) A.insert(a[i]);
  rep(i, b.size()) B.insert(b[i]);
  return A.size() > B.size();
}

void dfs(int cur) {

  if (found >= 2)
    return;

  if (cur >= len) {
    ++found;
    rep(i, answer.size()) if (isupper(answer[i])) answer[i] =
        transfer[answer[i] - 'A'];
    return;
  }

  int word_size = seq[cur].size();

  rep(i, (int)buf[word_size].size()) {
    string word = buf[word_size][i];

    int *backtrack = new int[word_size + 1];
    backtrack[0] = -1; // sentinel
    bool error = false;
    rep(j, word_size) {
      if (transfer[word[j] - 'A'] == '?' &&
          transfer[seq[cur][j] - 'A'] == '?') {
        backtrack[j] = 1, backtrack[j + 1] = -1;
        transfer[word[j] - 'A'] = seq[cur][j];
        transfer[seq[cur][j] - 'A'] = word[j];
      } else if (transfer[word[j] - 'A'] == seq[cur][j] &&
                 transfer[seq[cur][j] - 'A'] == word[j]) {
        backtrack[j] = 0;
      } else {
        backtrack[j] = -1;
        error = true;
        break;
      }
    }

    if (!error)
      dfs(cur + 1);

    int j = 0;
    while (backtrack[j] != -1 && j < word_size) {
      if (backtrack[j] == 1)
        transfer[word[j] - 'A'] = transfer[seq[cur][j] - 'A'] = '?';
      ++j;
    }
  }
}

int main() {
  while (cin >> n, n) {
    seq.clear();
    rep(i, 30) buf[i].clear();
    rep(i, n) {
      cin >> tmp;
      buf[(int)tmp.size()].push_back(tmp);
    }
    cin.ignore();
    getline(cin, sequence);
    stringstream ss(sequence.substr(0, (int)sequence.size() - 1));
    while (!(ss >> tmp).fail())
      seq.push_back(tmp);
    sort(seq.begin(), seq.end(), comp);

    answer = sequence;
    found = 0, len = (int)seq.size();
    rep(i, 26) transfer[i] = '?';
    dfs(0);

    cout << ((found == 1) ? answer : "-.") << endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>

#define REP(i, s, n) for (int i = s; i < n; i++)
#define rep(i, n) REP(i, 0, n)

using namespace std;

typedef long long ll;

int n, found, buf_length;
vector<string> word[30], buf;
string sequence;
char transfer[26];
vector<ll> bitmask;
vector<int> bc;
set<string> exist;
char table[26];

bool cmp(const string &a, const string &b) { return a.size() > b.size(); }

void dfs(int cur, long long bit) {

  if (found >= 2)
    return;

  // rep(i,26) cout << table[i] << " ";
  // cout << endl;

  if (cur >= buf_length) {
    found++;
    rep(i, 26) transfer[i] = table[i];
    return;
  }

  int len = buf[cur].size();

  if (__builtin_popcountll(bit & bitmask[cur]) == bc[cur]) {
    string tmp = buf[cur];
    rep(i, len) tmp[i] = table[tmp[i] - 'A'];
    if (exist.find(tmp) != exist.end())
      dfs(cur + 1, bit);
    return;
  }

  char tmp_table[26];
  rep(i, 26) tmp_table[i] = table[i];
  rep(i, word[len].size()) {
    // cout<< endl;
    // rep(j,26) cout << table[j] << " "; cout << endl;
    //  cout << "word " << word[len][i] << " is ";
    bool error = false;
    long long new_bit = bit;
    // rep(j,26) table[j] = tmp_table[j];
    rep(j, len) {

      if (table[buf[cur][j] - 'A'] == '?' &&
          table[word[len][i][j] - 'A'] == '?') {
        long long SHIFT = word[len][i][j] - 'A';
        new_bit |= (1LL << SHIFT);
        SHIFT = buf[cur][j] - 'A';
        new_bit |= (1LL << SHIFT);
        table[buf[cur][j] - 'A'] = word[len][i][j];
        table[word[len][i][j] - 'A'] = buf[cur][j];
      } else if (!(table[buf[cur][j] - 'A'] == word[len][i][j] &&
                   table[word[len][i][j] - 'A'] == buf[cur][j])) {
        // cout << "table[" << buf[cur][j] << "] != " << table[buf[cur][j]-'A']
        // << " ?= " << word[len][i][j] << endl; cout << "table[" <<
        // word[len][i][j] << "] != " << table[word[len][i][j]-'A'] << " ?= " <<
        // buf[cur][j] << endl;
        error = true;
        break;
      }
    }

    if (error) {
      // cout << "bad" << endl;
      continue;
    } // cout << "ok" << endl;
    dfs(cur + 1, new_bit);
    rep(j, len) {
      int idx = buf[cur][j] - 'A';
      table[idx] = tmp_table[idx];
      idx = word[len][i][j] - 'A';
      table[idx] = tmp_table[idx];
    }
    if (found >= 2)
      return;
  }
}

int main() {
  while (cin >> n, n) {
    string tmp;
    found = 0;
    buf.clear(), tmp.clear();
    rep(i, 26) transfer[i] = table[i] = '?';
    rep(i, 30) word[i].clear();
    rep(i, n) {
      cin >> tmp;
      word[(int)tmp.size()].push_back(tmp);
      exist.insert(tmp);
    }
    cin.ignore();
    getline(cin, sequence);
    tmp = sequence.substr(0, (int)sequence.size() - 1);
    stringstream ss(tmp);
    while (!(ss >> tmp).fail())
      buf.push_back(tmp);

    sort(buf.begin(), buf.end(), cmp);
    buf.erase(unique(buf.begin(), buf.end()), buf.end());
    buf_length = (int)buf.size();
    bitmask.clear(), bc.clear();
    bitmask.resize(buf_length, 0), bc.resize(buf_length);
    rep(i, buf_length) {
      rep(j, buf[i].size()) {
        long long SHIFT = buf[i][j] - 'A';
        bitmask[i] |= (1LL << SHIFT);
      }
      bc[i] = __builtin_popcountll(bitmask[i]);
    }

    dfs(0, 0LL);

    if (found == 1) {
      rep(i, sequence.size()) cout
          << (isupper(sequence[i]) ? transfer[sequence[i] - 'A'] : sequence[i]);
      puts("");
    } else
      puts("-.");
  }
  return 0;
}