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

#include <algorithm>
#include <cassert>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>

using namespace std;

#define LOG(...) printf(__VA_ARGS__)
// #define LOG(...)
#define FOR(i, a, b) for (int i = (int)(a); i < (int)(b); ++i)
#define REP(i, n) for (int i = 0; i < (int)(n); ++i)
#define ALL(a) (a).begin(), (a).end()
#define RALL(a) (a).rbegin(), (a).rend()
#define EXIST(s, e) ((s).find(e) != (s).end())
#define SORT(c) sort((c).begin(), (c).end())
#define RSORT(c) sort((c).rbegin(), (c).rend())
#define CLR(a) memset((a), 0, sizeof(a))

typedef long long ll;
typedef unsigned long long ull;
typedef vector<bool> vb;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef vector<vb> vvb;
typedef vector<vi> vvi;
typedef vector<vll> vvll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

const int dx[] = {-1, 0, 1, 0};
const int dy[] = {0, 1, 0, -1};

struct UnionFind {
  vector<int> v;
  UnionFind(int n) : v(n) {
    for (int i = 0; i < n; i++)
      v[i] = i;
  }
  int find(int x) { return v[x] == x ? x : v[x] = find(v[x]); }
  void unite(int x, int y) { v[find(x)] = find(y); }
};
set<char> nzero;
map<char, int> mci;
vector<char> vc;
vector<char> vc2;
int key = 0;
vector<pii> sip;
vector<pii> sia;
void saiki(int idx, int num, bool pre) {
  if (idx == 0) {
    if (pre) {
      sip.push_back({num, key});
    } else {
      sia.push_back({num, key});
    }
    return;
  }
  vector<char> vcc;
  if (pre)
    vcc = vc;
  else
    vcc = vc2;
  REP(i, 10) {
    if (i == 0 && nzero.find(vcc[vcc.size() - idx]) != nzero.end())
      continue;
    if (!(key & (1 << i))) {
      key |= (1 << i);
      saiki(idx - 1, num + i * mci[vcc[vcc.size() - idx]], pre);
      key &= ~(1 << i);
    }
  }
}

int main() {
  int n;
  while (cin >> n, n) {
    nzero.clear();
    mci.clear();
    vc.clear();
    key = 0;
    sip.clear();
    sia.clear();
    vector<string> s(n);
    REP(i, n) {
      cin >> s[i];
      if (s[i].length() != 1)
        nzero.insert(s[i][0]);
      REP(j, s[i].length()) {
        vc.push_back(s[i][j]);
        if (mci.find(s[i][j]) == mci.end()) {
          mci[s[i][j]] = 0;
        }
        if (i != n - 1) {
          mci[s[i][j]] += (int)pow(10, s[i].length() - j - 1);
        } else {
          mci[s[i][j]] -= (int)pow(10, s[i].length() - j - 1);
        }
      }
    }
    /*
    vi nums;
    for (auto x : mci) {
            nums.push_back(x.second);
    }
    SORT(nums);
    REP(i, nums.size()) {
            if (nums[i] > 0) {
                    reverse(nums.begin() + i, nums.end());
                    break;
            }
    }
    */
    SORT(vc);
    vc.erase(std::unique(vc.begin(), vc.end()), vc.end());
    /*
    vector<char> vc2;
    REP(i, mci.size()) {
            REP(j, vc.size()) {
                    if (nums[i] == mci[vc[j]]) {
                            vc2.push_back(vc[j]);
                            vc.erase(vc.begin()+j);
                    }
            }
    }
    vc = vc2;
    */
    vc2 = vc;
    vc.erase(vc.begin() + vc.size() / 2, vc.end());
    vc2.erase(vc2.begin(), vc2.begin() + vc2.size() / 2);
    saiki(vc.size(), 0, true);
    saiki(vc2.size(), 0, false);
    SORT(sip);
    RSORT(sia);
    int ans = 0;
    int right = 0;
    REP(i, sip.size())
    FOR(j, right, sia.size())
    if (sip[i].first + sia[j].first == 0) {
      if ((sip[i].second & sia[j].second) == 0)
        ans++;
    } else if (sip[i].first + sia[j].first < 0) {
      break;
    } else {
      right = j;
    }

    cout << ans << endl;
  }
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cassert>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>

using namespace std;

#define LOG(...) printf(__VA_ARGS__)
// #define LOG(...)
#define FOR(i, a, b) for (int i = (int)(a); i < (int)(b); ++i)
#define REP(i, n) for (int i = 0; i < (int)(n); ++i)
#define ALL(a) (a).begin(), (a).end()
#define RALL(a) (a).rbegin(), (a).rend()
#define EXIST(s, e) ((s).find(e) != (s).end())
#define SORT(c) sort((c).begin(), (c).end())
#define RSORT(c) sort((c).rbegin(), (c).rend())
#define CLR(a) memset((a), 0, sizeof(a))

typedef long long ll;
typedef unsigned long long ull;
typedef vector<bool> vb;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef vector<vb> vvb;
typedef vector<vi> vvi;
typedef vector<vll> vvll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

const int dx[] = {-1, 0, 1, 0};
const int dy[] = {0, 1, 0, -1};

struct UnionFind {
  vector<int> v;
  UnionFind(int n) : v(n) {
    for (int i = 0; i < n; i++)
      v[i] = i;
  }
  int find(int x) { return v[x] == x ? x : v[x] = find(v[x]); }
  void unite(int x, int y) { v[find(x)] = find(y); }
};
set<char> nzero;
map<char, int> mci;
vector<char> vc;
vector<char> vc2;
int key = 0;
vector<pii> sip;
vector<pii> sia;
void saiki(int idx, int num, bool pre) {
  if (idx == 0) {
    if (pre) {
      sip.push_back({num, key});
    } else {
      sia.push_back({num, key});
    }
    return;
  }
  vector<char> vcc;
  if (pre)
    vcc = vc;
  else
    vcc = vc2;
  REP(i, 10) {
    if (i == 0 && nzero.find(vcc[vcc.size() - idx]) != nzero.end())
      continue;
    if (!(key & (1 << i))) {
      key |= (1 << i);
      saiki(idx - 1, num + i * mci[vcc[vcc.size() - idx]], pre);
      key &= ~(1 << i);
    }
  }
}

int main() {
  int n;
  while (cin >> n, n) {
    nzero.clear();
    mci.clear();
    vc.clear();
    key = 0;
    sip.clear();
    sia.clear();
    vector<string> s(n);
    REP(i, n) {
      cin >> s[i];
      if (s[i].length() != 1)
        nzero.insert(s[i][0]);
      REP(j, s[i].length()) {
        vc.push_back(s[i][j]);
        if (mci.find(s[i][j]) == mci.end()) {
          mci[s[i][j]] = 0;
        }
        if (i != n - 1) {
          mci[s[i][j]] += (int)pow(10, s[i].length() - j - 1);
        } else {
          mci[s[i][j]] -= (int)pow(10, s[i].length() - j - 1);
        }
      }
    }
    /*
    vi nums;
    for (auto x : mci) {
            nums.push_back(x.second);
    }
    SORT(nums);
    REP(i, nums.size()) {
            if (nums[i] > 0) {
                    reverse(nums.begin() + i, nums.end());
                    break;
            }
    }
    */
    SORT(vc);
    vc.erase(std::unique(vc.begin(), vc.end()), vc.end());
    /*
    vector<char> vc2;
    REP(i, mci.size()) {
            REP(j, vc.size()) {
                    if (nums[i] == mci[vc[j]]) {
                            vc2.push_back(vc[j]);
                            vc.erase(vc.begin()+j);
                    }
            }
    }
    vc = vc2;
    */
    vc2 = vc;
    vc.erase(vc.begin() + vc.size() / 2, vc.end());
    vc2.erase(vc2.begin(), vc2.begin() + vc2.size() / 2);
    saiki(vc.size(), 0, true);
    saiki(vc2.size(), 0, false);
    SORT(sip);
    SORT(sia);
    int ans = 0;
    REP(i, sip.size())
    REP(j, sia.size())
    if (sip[i].first + sia[j].first == 0) {
      if ((sip[i].second & sia[j].second) == 0)
        ans++;
    } else if (sip[i].first + sia[j].first > 0) {
      continue;
    }

    cout << ans << endl;
  }
}