Problem p01908 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>
using namespace std;
#define rep(i, a, b) for (int i = a; i < b; i++)

string _s;
int _n;
int sa_k;
vector<int> Rank, tmp, sa, lcp;
bool cmp_sa(int i, int j) {
  if (Rank[i] != Rank[j])
    return Rank[i] < Rank[j];
  return (i + sa_k <= _n ? Rank[i + sa_k] : -1) <
         (j + sa_k <= _n ? Rank[j + sa_k] : -1);
}
void construct_sa() {
  for (int i = 0; i <= _n; i++) {
    sa[i] = i;
    Rank[i] = i < _n ? _s[i] : -1;
  }
  for (sa_k = 1; sa_k <= _n; sa_k *= 2) {
    sort(sa.begin(), sa.end(), cmp_sa);
    tmp[sa[0]] = 0;
    for (int i = 1; i <= _n; i++)
      tmp[sa[i]] = tmp[sa[i - 1]] + (cmp_sa(sa[i - 1], sa[i]) ? 1 : 0);
    for (int i = 0; i <= _n; i++)
      Rank[i] = tmp[i];
  }
}
void construct_lcp() {
  for (int i = 0; i <= _n; i++)
    Rank[sa[i]] = i;
  int h = 0;
  lcp[0] = 0;
  for (int i = 0; i < _n; i++) {
    int j = sa[Rank[i] - 1];
    if (h > 0)
      h--;
    for (; j + h < _n && i + h < _n; h++)
      if (_s[j + h] != _s[i + h])
        break;
    lcp[Rank[i] - 1] = h;
  }
}
void init(string s) {
  _s = s;
  _n = s.length();
  Rank = vector<int>(_n + 1);
  tmp = vector<int>(_n + 1);
  sa = vector<int>(_n + 1);
  lcp = vector<int>(_n + 1);
  construct_sa();
  construct_lcp();
}
bool chk(string s) {
  int lo = 0, hi = _n + 1;
  while (lo + 1 != hi) {
    int md = (lo + hi) / 2;
    if (s <= _s.substr(sa[md]))
      hi = md;
    else
      lo = md;
  }

  string t = _s.substr(sa[hi], s.length());
  return s == t;
}
//-----------------------------------------------------------------------------------
int N;
string S[101010];
//-----------------------------------------------------------------------------------
#define rrep(i, a, b) for (int i = a; i >= b; i--)
string nxt(string x) {
  int carry = 1;
  rrep(i, x.length() - 1, 0) {
    int n = x[i] - 'a' + carry;
    carry = 0;
    if (26 <= n) {
      n %= 26;
      carry = 1;
    }
    x[i] = 'a' + n;
  }
  if (carry)
    x = "a" + x;
  return x;
}
//-----------------------------------------------------------------------------------
int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  cin >> N;
  rep(i, 0, N) cin >> S[i];

  string SS = "";
  rep(i, 0, N) SS += "#" + S[i];
  init(SS);

  string ans = "a";
  while (chk(ans))
    ans = nxt(ans);
  cout << ans << endl;
}

Fixed submission:
#include <bits/stdc++.h>
using namespace std;
#define rep(i, a, b) for (int i = a; i < b; i++)

string _s;
int _n;
int sa_k;
vector<int> Rank, tmp, sa, lcp;
bool cmp_sa(int i, int j) {
  if (Rank[i] != Rank[j])
    return Rank[i] < Rank[j];
  return (i + sa_k <= _n ? Rank[i + sa_k] : -1) <
         (j + sa_k <= _n ? Rank[j + sa_k] : -1);
}
void construct_sa() {
  for (int i = 0; i <= _n; i++) {
    sa[i] = i;
    Rank[i] = i < _n ? _s[i] : -1;
  }
  for (sa_k = 1; sa_k <= _n; sa_k *= 2) {
    sort(sa.begin(), sa.end(), cmp_sa);
    tmp[sa[0]] = 0;
    for (int i = 1; i <= _n; i++)
      tmp[sa[i]] = tmp[sa[i - 1]] + (cmp_sa(sa[i - 1], sa[i]) ? 1 : 0);
    for (int i = 0; i <= _n; i++)
      Rank[i] = tmp[i];
  }
}
void construct_lcp() {
  for (int i = 0; i <= _n; i++)
    Rank[sa[i]] = i;
  int h = 0;
  lcp[0] = 0;
  for (int i = 0; i < _n; i++) {
    int j = sa[Rank[i] - 1];
    if (h > 0)
      h--;
    for (; j + h < _n && i + h < _n; h++)
      if (_s[j + h] != _s[i + h])
        break;
    lcp[Rank[i] - 1] = h;
  }
}
void init(string s) {
  _s = s;
  _n = s.length();
  Rank = vector<int>(_n + 1);
  tmp = vector<int>(_n + 1);
  sa = vector<int>(_n + 1);
  lcp = vector<int>(_n + 1);
  construct_sa();
  construct_lcp();
}
bool chk(string s) {
  int lo = 0, hi = _n + 1;
  while (lo + 1 != hi) {
    int md = (lo + hi) / 2;
    if (s <= _s.substr(sa[md], s.length()))
      hi = md;
    else
      lo = md;
  }

  string t = _s.substr(sa[hi], s.length());
  return s == t;
}
//-----------------------------------------------------------------------------------
int N;
string S[101010];
//-----------------------------------------------------------------------------------
#define rrep(i, a, b) for (int i = a; i >= b; i--)
string nxt(string x) {
  int carry = 1;
  rrep(i, x.length() - 1, 0) {
    int n = x[i] - 'a' + carry;
    carry = 0;
    if (26 <= n) {
      n %= 26;
      carry = 1;
    }
    x[i] = 'a' + n;
  }
  if (carry)
    x = "a" + x;
  return x;
}
//-----------------------------------------------------------------------------------
int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  cin >> N;
  rep(i, 0, N) cin >> S[i];

  string SS = "";
  rep(i, 0, N) SS += "#" + S[i];
  init(SS);

  string ans = "a";
  while (chk(ans))
    ans = nxt(ans);
  cout << ans << endl;
}