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

#include <algorithm>
#include <functional>
#include <iostream>
#include <map>
#include <string>
#include <vector>

#define REP(i, a, b) for (int i = int(a); i < int(b); i++)
#define dump(val) cerr << __LINE__ << ":\\t" << #val << " = " << (val) << endl

using namespace std;

typedef long long int lli;

template <typename T> vector<T> make_v(size_t a, T b) {
  return vector<T>(a, b);
}

template <typename... Ts> auto make_v(size_t a, Ts... ts) {
  return vector<decltype(make_v(ts...))>(a, make_v(ts...));
}

int main() {
  int n;
  while (cin >> n, n) {
    vector<string> v(n);
    vector<char> cv;
    int isF[26] = {0};
    lli coef[26] = {0LL};
    REP(i, 0, n) {
      cin >> v[i];
      for (char &c : v[i]) {
        cv.push_back(c);
      }
      if (v[i].size() != 1) {
        isF[v[i][0] - 'A'] = 1;
      }
      for (int j = v[i].size() - 1, bs = 1; j >= 0; j--, bs *= 10) {
        coef[v[i][j] - 'A'] += (2 * (i + 1 != n) - 1) * bs;
      }
    }
    sort(begin(cv), end(cv));
    cv.erase(unique(begin(cv), end(cv)), end(cv));
    map<lli, vector<int>> mp1, mp2;

    int arr[26] = {0};
    function<void(int, int, int, int, map<lli, vector<int>> &)> dfs =
        [&](int srt, int pos, int tar, int used, map<lli, vector<int>> &mp) {
          if (pos == tar) {
            lli sum = 0;
            REP(i, srt, pos) { sum += coef[cv[i] - 'A'] * arr[cv[i] - 'A']; }
            mp[sum].push_back(used);
            return;
          }
          REP(i, 0, 10) {
            if (isF[cv[pos] - 'A'] && i == 0)
              continue;
            int u = 1 << i;
            if ((used & u) == u)
              continue;
            arr[cv[pos] - 'A'] = i;
            dfs(srt, pos + 1, tar, used | u, mp);
          }
        };
    dfs(0, 0, cv.size() / 2, 0, mp1);
    dfs(cv.size() / 2, cv.size() / 2, cv.size(), 0, mp2);
    int ans = 0;
    for (auto &p : mp1) {
      auto &q = mp2[-p.first];
      for (auto i1 : p.second) {
        for (auto i2 : q) {
          if ((i1 & i2) == 0) {
            ans++;
          }
        }
      }
    }
    cout << ans << endl;
  }
  return 0;
}


Error: TLE

Fixed submission:

#include <algorithm>
#include <functional>
#include <iostream>
#include <string>
#include <vector>

#define REP(i, a, b) for (int i = int(a); i < int(b); i++)
#define dump(val) cerr << __LINE__ << ":\\t" << #val << " = " << (val) << endl

using namespace std;

typedef long long int lli;

template <typename T> vector<T> make_v(size_t a, T b) {
  return vector<T>(a, b);
}

template <typename... Ts> auto make_v(size_t a, Ts... ts) {
  return vector<decltype(make_v(ts...))>(a, make_v(ts...));
}

template <class BidirectionalIterator>
bool next_combination(BidirectionalIterator first1, BidirectionalIterator last1,
                      BidirectionalIterator first2,
                      BidirectionalIterator last2) {
  if ((first1 == last1) || (first2 == last2))
    return false;
  BidirectionalIterator m1 = last1;
  BidirectionalIterator m2 = last2;
  --m2;
  while (--m1 != first1 && !(*m1 < *m2))
    ;
  bool result = (m1 == first1) && !(*first1 < *m2);
  if (!result) {
    while (first2 != m2 && !(*m1 < *first2))
      ++first2;
    first1 = m1;
    std::iter_swap(first1, first2);
    ++first1;
    ++first2;
  }
  if ((first1 != last1) && (first2 != last2)) {
    m1 = last1;
    m2 = first2;
    while ((m1 != first1) && (m2 != last2)) {
      std::iter_swap(--m1, m2);
      ++m2;
    }
    std::reverse(first1, m1);
    std::reverse(first1, last1);
    std::reverse(m2, last2);
    std::reverse(first2, last2);
  }
  return !result;
}

template <class BidirectionalIterator>
bool next_combination(BidirectionalIterator first, BidirectionalIterator middle,
                      BidirectionalIterator last) {
  return next_combination(first, middle, middle, last);
}

int main() {
  int n;
  while (cin >> n, n) {
    vector<string> v(n);
    vector<char> cv;
    REP(i, 0, n) {
      cin >> v[i];
      for (char &c : v[i]) {
        cv.push_back(c);
      }
    }
    sort(begin(cv), end(cv));
    cv.erase(unique(begin(cv), end(cv)), end(cv));

    vector<int> nmb(10);
    REP(i, 0, 10) { nmb[i] = i; }
    int ans = 0;
    do {
      do {
        int arr[26] = {0};
        REP(i, 0, cv.size()) { arr[cv[i] - 'A'] = nmb[i]; }
        lli sum = 0;
        bool flg = true;
        REP(i, 0, v.size()) {
          lli t = 0;
          REP(j, 0, v[i].size()) {
            if (j == 0 && v[i].size() != 1 && arr[v[i][j] - 'A'] == 0) {
              flg = false;
              break;
            }
            t = t * 10 + arr[v[i][j] - 'A'];
          }
          if (flg) {
            if (i + 1 != v.size()) {
              sum += t;
            } else {
              sum -= t;
            }
          }
        }
        /*
        if (flg && (sum == 0)) {
            REP(i, 0, cv.size()) {
                cout << cv[i] << ' ' << nmb[i] << endl;
            }
            cout << "----" << endl;
        }
        */
        ans += (flg && (sum == 0));
      } while (next_permutation(begin(nmb), begin(nmb) + cv.size()));
    } while (next_combination(begin(nmb), begin(nmb) + cv.size(), end(nmb)));
    cout << ans << endl;

    /*
    //TLE
    vector<bool> used(10, false);
    vector<int> c2i(26, -1);
    function<int(int)> rec = [&](int s) -> int {
        if (s == cv.size()) {
            lli ans = 0;
            REP(i, 0, v.size()) {
                lli t = 0;
                if (v[i].size() == 1) {
                    t = (c2i[v[i][0] - 'A']);
                } else {
                    REP(j, 0, v[i].size()) {
                        if (j == 0 && c2i[v[i][j] - 'A'] == 0) return 0;
                        t = 10 * t + (c2i[v[i][j] - 'A']);
                    }
                }
                if (i + 1 == v.size()) {
                    t = -t;
                }
                ans += t;
            }
            return (ans == 0);
        }
        int ans = 0;
        REP(i, 0, 10) {
            if (used[i]) continue;
            used[i] = true;
            c2i[cv[s] - 'A'] = i;
            ans += rec(s + 1);
            used[i] = false;
            c2i[cv[s] - 'A'] = -1;
        }
        return ans;
    };
    cout << rec(0) << endl;
    //*/
  }
  return 0;
}