This documentation is automatically generated by online-judge-tools/verification-helper
#include "String/SuffixArray.hpp"
vector<int> SuffixArray(string S)
$S$ について(空文字を含む)SuffixArrayを返す. $S$ の長さを $N$ として、長さ $ N+1 $ の配列を返す.
接尾辞(先頭から $ n \in {0, \ldots, N } $ 文字を取り除いた文字列)を,辞書順に並べたもの.
たとえばsuffixarray
について,
$n$ | 接尾辞 |
---|---|
0 | suffixarray |
1 | uffixarray |
2 | ffixarray |
3 | fixarray |
4 | ixarray |
5 | xarray |
6 | array |
7 | rray |
8 | ray |
9 | ay |
10 | y |
11 | ` ` |
である.これを接尾辞について辞書順に並び変えると,
$n$ | 接尾辞 |
---|---|
11 | ` ` |
6 | array |
9 | ay |
2 | ffixarray |
3 | fixarray |
4 | ixarray |
8 | ray |
7 | rray |
0 | suffixarray |
1 | uffixarray |
5 | xarray |
10 | y |
となるので,suffixarray
のSuffixArrayは{11, 6, 9, 2, 3, 4, 8, 7, 0, 1, 5, 10}
である.よってこれが返る.
vector<int> SuffixArray(const string& s) {
int n = s.size(), k;
vector<int> sa(n + 1);
vector<int> rank(n + 1);
for (int i = 0; i <= n; i++) {
sa[i] = i;
rank[i] = i < n ? (int)s[i] : -1;
}
auto compare = [&](int a, int b) {
if (rank[a] != rank[b]) return rank[a] < rank[b];
auto rank_ak = a + k <= n ? rank[a + k] : -1;
auto rank_bk = b + k <= n ? rank[b + k] : -1;
return rank_ak < rank_bk;
};
for (k = 1; k <= n; k *= 2) {
sort(sa.begin(), sa.end(), compare);
vector<int> tmp(n + 1);
tmp[sa[0]] = 0;
for (int i = 1; i <= n; i++) {
tmp[sa[i]] = tmp[sa[i - 1]] + (compare(sa[i - 1], sa[i]) ? 1 : 0);
}
for (int i = 0; i <= n; i++) {
rank[i] = tmp[i];
}
}
return sa;
}
#line 1 "String/SuffixArray.hpp"
vector<int> SuffixArray(const string& s) {
int n = s.size(), k;
vector<int> sa(n + 1);
vector<int> rank(n + 1);
for (int i = 0; i <= n; i++) {
sa[i] = i;
rank[i] = i < n ? (int)s[i] : -1;
}
auto compare = [&](int a, int b) {
if (rank[a] != rank[b]) return rank[a] < rank[b];
auto rank_ak = a + k <= n ? rank[a + k] : -1;
auto rank_bk = b + k <= n ? rank[b + k] : -1;
return rank_ak < rank_bk;
};
for (k = 1; k <= n; k *= 2) {
sort(sa.begin(), sa.end(), compare);
vector<int> tmp(n + 1);
tmp[sa[0]] = 0;
for (int i = 1; i <= n; i++) {
tmp[sa[i]] = tmp[sa[i - 1]] + (compare(sa[i - 1], sa[i]) ? 1 : 0);
}
for (int i = 0; i <= n; i++) {
rank[i] = tmp[i];
}
}
return sa;
}