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

#include "bits/stdc++.h"
#include <unordered_map>
#include <unordered_set>
#pragma warning(disable : 4996)
using namespace std;
using ld = long double;
template <class T> using Table = vector<vector<T>>;
const ld eps = 1e-9;

//// < "D:\\D_Download\\Visual Studio
///2015\\Projects\\programing_contest_c++\\Debug\\a.txt" > "D:\\D_Download\\Visual
///Studio 2015\\Projects\\programing_contest_c++\\Debug\\b.txt"

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

string T, P;
struct SuffixArray {
  struct SAComp {
    const int h;
    const vector<int> &g;
    SAComp(const int h_, const vector<int> &g_) : h(h_), g(g_) { ; }
    bool operator()(int a, int b) {
      return a == b ? false : g[a] != g[b] ? g[a] < g[b] : g[a + h] < g[b + h];
    }
  };

  static const int SIZE = 100000;
  int n;
  string str;
  vector<int> sa;
  vector<int> lcp;

  SuffixArray() { ; }
  SuffixArray(const string t) : str(t) { Init(); }
  void Init() {
    n = str.size();
    buildSA();
    buildLCP();
  }

  // O(mlogn)

  ////??????°????????????
  // int find(const string p) {
  //   int m = p.size();
  //   int left = 0;
  //   int right = n-m;
  //   while (left < right) {
  //       int mid = (left + right) / 2;
  //       if (str.substr(sa[mid],m)<p.substr(0,m)) { left = mid + 1; }
  //       else { right = mid; }
  //   }
  //   return str.substr(sa[left], m)== p.substr(0, m)? sa[left] : -1;
  // }
private:
  // O(nlog^2n)
  void buildSA() {
    sa = vector<int>(n + 1);
    vector<int> g(n + 1);
    vector<int> b(n + 1);
    REP(i, n + 1) {
      sa[i] = i;
      g[i] = str[i];
    }
    b[0] = 0;
    b[n] = 0;
    SAComp f(0, g);
    sort(sa.begin(), sa.end(), SAComp(0, g));
    for (int h = 1; b[n] != n; h *= 2) {
      SAComp comp(h, g);
      sort(sa.begin(), sa.end(), comp);
      REP(i, n) b[i + 1] = b[i] + comp(sa[i], sa[i + 1]);
      REP(i, n + 1) g[sa[i]] = b[i];
    }
  }
  void buildLCP() {
    lcp = vector<int>(n + 1);
    int h = 0;
    vector<int> b(n + 1);
    REP(i, n + 1) { b[sa[i]] = i; }
    REP(i, n + 1) {
      if (b[i]) {
        for (int j = sa[b[i] - 1];
             j + h < n && i + h < n && str[j + h] == str[i + h]; h++) {
          ;
        }
        lcp[b[i]] = h;
      } else {
        lcp[b[i]] = -1;
      }
      if (h > 0) {
        h--;
      }
    }
  }
};

int main() {
  cin >> T >> P;
  vector<int> newsa;
  {
    SuffixArray asa(T);
    vector<int> oldsa = asa.sa;
    for (auto s : oldsa) {
      newsa.push_back(s);
    }
  }

  int r, l;
  {
    int amin = -1;
    int amax = newsa.size();
    while (amin + 1 != amax) {
      int amid = (amin + amax) / 2;
      string ast = T.substr(newsa[amid], P.size());
      if (ast <= P)
        amin = amid;
      else
        amax = amid;
    }
    r = amax;
  }
  {
    int amin = -1;
    int amax = newsa.size();
    while (amin + 1 != amax) {
      int amid = (amin + amax) / 2;
      string ast = T.substr(newsa[amid], P.size());
      if (ast < P)
        amin = amid;
      else
        amax = amid;
    }
    l = amax;
  }
  vector<int> nums;
  for (int i = l; i < r; ++i) {
    nums.push_back(newsa[i]);
  }
  sort(nums.begin(), nums.end());
  for (auto n : nums) {
    printf("%d\\n", n);
  }

  return 0;
}

Error: TLE

Fixed submission:

#include "bits/stdc++.h"
#include <unordered_map>
#include <unordered_set>
#pragma warning(disable : 4996)
using namespace std;
using ld = long double;
template <class T> using Table = vector<vector<T>>;
const ld eps = 1e-9;

//// < "D:\\D_Download\\Visual Studio
///2015\\Projects\\programing_contest_c++\\Debug\\a.txt" > "D:\\D_Download\\Visual
///Studio 2015\\Projects\\programing_contest_c++\\Debug\\b.txt"

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

string T, P;
struct SuffixArray {
  struct SAComp {
    const int h;
    const vector<int> &g;
    SAComp(const int h_, const vector<int> &g_) : h(h_), g(g_) { ; }
    bool operator()(int a, int b) {
      return a == b ? false : g[a] != g[b] ? g[a] < g[b] : g[a + h] < g[b + h];
    }
  };

  static const int SIZE = 100000;
  int n;
  string str;
  vector<int> sa;
  vector<int> lcp;

  SuffixArray() { ; }
  SuffixArray(const string t) : str(t) { Init(); }
  void Init() {
    n = str.size();
    buildSA();
    buildLCP();
  }

  // O(mlogn)

  ////??????°????????????
  // int find(const string p) {
  //   int m = p.size();
  //   int left = 0;
  //   int right = n-m;
  //   while (left < right) {
  //       int mid = (left + right) / 2;
  //       if (str.substr(sa[mid],m)<p.substr(0,m)) { left = mid + 1; }
  //       else { right = mid; }
  //   }
  //   return str.substr(sa[left], m)== p.substr(0, m)? sa[left] : -1;
  // }
private:
  // O(nlog^2n)
  void buildSA() {
    sa = vector<int>(n + 1);
    vector<int> g(n + 1);
    vector<int> b(n + 1);
    REP(i, n + 1) {
      sa[i] = i;
      g[i] = str[i];
    }
    b[0] = 0;
    b[n] = 0;
    SAComp f(0, g);
    sort(sa.begin(), sa.end(), SAComp(0, g));
    for (int h = 1; b[n] != n; h *= 2) {
      SAComp comp(h, g);
      sort(sa.begin(), sa.end(), comp);
      REP(i, n) b[i + 1] = b[i] + comp(sa[i], sa[i + 1]);
      REP(i, n + 1) g[sa[i]] = b[i];
    }
  }
  void buildLCP() {
    lcp = vector<int>(n + 1);
    int h = 0;
    vector<int> b(n + 1);
    REP(i, n + 1) { b[sa[i]] = i; }
    REP(i, n + 1) {
      if (b[i]) {
        for (int j = sa[b[i] - 1];
             j + h < n && i + h < n && str[j + h] == str[i + h]; h++) {
          ;
        }
        lcp[b[i]] = h;
      } else {
        lcp[b[i]] = -1;
      }
      if (h > 0) {
        h--;
      }
    }
  }
};

int main() {
  cin >> T >> P;
  vector<int> newsa;
  {
    SuffixArray asa(T);
    vector<int> oldsa = asa.sa;
    for (auto s : oldsa) {
      newsa.push_back(s);
    }
  }

  int r, l;
  {
    int amin = -1;
    int amax = newsa.size();
    while (amin + 1 != amax) {
      int amid = (amin + amax) / 2;
      string ast = T.substr(newsa[amid], P.size());
      if (ast <= P)
        amin = amid;
      else
        amax = amid;
    }
    r = amax;
  }
  {
    int amin = -1;
    int amax = newsa.size();
    while (amin + 1 != amax) {
      int amid = (amin + amax) / 2;
      string ast = T.substr(newsa[amid], P.size());
      if (ast < P)
        amin = amid;
      else
        amax = amid;
    }
    l = amax;
  }
  vector<int> nums;
  for (int i = l; i < r; ++i) {
    nums.push_back(newsa[i]);
  }
  sort(nums.begin(), nums.end());
  for (auto n : nums) {
    cout << n << endl;
  }

  return 0;
}