-
Notifications
You must be signed in to change notification settings - Fork 6
/
anothersubstringqueryproblem.cpp
105 lines (96 loc) · 2.74 KB
/
anothersubstringqueryproblem.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
// https://github.com/stevenhalim/cpbook-code/blob/master/ch6/sa_lcp.cpp
#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> ii;
typedef vector<int> vi;
class SuffixArray {
private:
vi RA;
void countingSort(int k) {
int maxi = max(300, n);
vi c(maxi, 0);
for (int i = 0; i < n; ++i)
++c[i+k < n ? RA[i+k] : 0];
for (int i = 0, ss = 0; i < maxi; ++i) {
int t = c[i]; c[i] = ss; ss += t;
}
vi temp(n);
for (int i = 0; i < n; ++i)
temp[c[SA[i]+k < n ? RA[SA[i]+k] : 0]++] = SA[i];
swap(SA, temp);
}
void constructSA() {
SA.resize(n);
iota(SA.begin(), SA.end(), 0);
RA.resize(n);
for (int i = 0; i < n; ++i) RA[i] = T[i];
for (int k = 1; k < n; k <<= 1) {
countingSort(k);
countingSort(0);
vi temp(n);
int r = 0;
temp[SA[0]] = r;
for (int i = 1; i < n; ++i)
temp[SA[i]] =
((RA[SA[i]] == RA[SA[i-1]]) && (RA[SA[i]+k] == RA[SA[i-1]+k])) ? r : ++r;
swap(RA, temp);
if (RA[SA[n-1]] == n-1) break;
}
}
public:
string T;
const int n;
vi SA;
SuffixArray(string initialT) : T(initialT), n(initialT.size()) {
constructSA();
}
ii stringMatching(string P) {
int m = (int)P.size();
int lo = 0, hi = n-1;
while (lo < hi) {
int mid = (lo+hi) / 2;
int res = T.compare(SA[mid], m, P);
(res >= 0) ? hi = mid : lo = mid+1;
}
if (T.compare(SA[lo], m, P) != 0) return {-1, -1};
ii ans; ans.first = lo;
hi = n-1;
while (lo < hi) {
int mid = (lo+hi) / 2;
int res = T.compare(SA[mid], m, P);
(res > 0) ? hi = mid : lo = mid+1;
}
if (T.compare(SA[hi], m, P) != 0) --hi;
ans.second = hi;
return ans;
}
};
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
int n, lo, hi, k;
unordered_map<string, vi> h, q;
string p, s, t;
getline(cin, s);
cin >> n;
int z[n];
ii ans;
for (int i = 0; i < n; i++) {
cin >> t >> k; h[t].push_back(k); q[t].push_back(i);
}
s += char(0);
SuffixArray sa(s);
for (auto& [t, vv] : h) {
ans = sa.stringMatching(t);
lo = ans.first; hi = ans.second;
vi v;
if (lo+1 || hi+1) {
for (int j = lo; j <= hi; j++) v.push_back(sa.SA[j]);
sort(v.begin(), v.end());
}
for (int i = 0; i < h[t].size(); i++) z[q[t][i]] = (v.size() < h[t][i]) ? -1 : v[h[t][i]-1]+1;
}
for (int i : z) cout << i << '\n';
return 0;
}