classSuffixArray { public: int n; vector<int> rank, sa, height;
voidwork(const vector<pair<pair<int, int>, int>>& a){ vector<vector<pair<pair<int, int>, int>>> go(n); vector<pair<pair<int, int>, int>> now; for (auto tmp : a) { if (tmp.first.second == -1) now.push_back(tmp); else go[tmp.first.second].push_back(tmp); } for (int i = 0; i < n; i++) { for (auto tmp : go[i]) now.push_back(tmp); } for (int i = 0; i < n; i++) go[i].clear(); for (auto tmp : now) go[tmp.first.first].push_back(tmp); now.clear(); for (int i = 0; i < n; i++) { for (auto tmp : go[i]) now.push_back(tmp); } rank[now[0].second] = 0; for (int i = 1, p = 0; i < n; i++) { if (now[i].first != now[i-1].first) p++; rank[now[i].second] = p; } }
voidGetSuffixArray(const string& s){ n = s.length(); rank.resize(n); sa.resize(n); height.resize(n); vector<pair<pair<int, int>, int>> a(n); for (int i = 0; i < n; i++) a[i] = make_pair(make_pair(s[i], -1), i); sort(a.begin(), a.end()); rank[a[0].second] = 0; for (int i = 1, p = 0; i < n; i++) { if (a[i].first != a[i-1].first) p++; rank[a[i].second] = p; } for (int k = 1; k < n; k <<= 1) { for (int i = 0; i < n; i++) a[i] = make_pair(make_pair(rank[i], i + k >= n ? -1 : rank[i + k]), i); work(a); } for (int i = 0; i < n; i++) sa[rank[i]] = i; for (int i = 0, p = 0; i < n; i++) { if (rank[i] == 0) continue; int a = i, b = sa[rank[i] - 1]; while (a + p < n && b + p < n && s[a + p] == s[b + p]) p++; height[rank[i]] = p; if (p > 0) p--; } } };
classSolution { public: string lastSubstring(string s){ SuffixArray sa; sa.GetSuffixArray(s); int t = sa.sa[sa.n - 1]; return s.substr(t); } };