This documentation is automatically generated by online-judge-tools/verification-helper
View the Project on GitHub granddaifuku/library
#define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ALDS1_14_D&lang=jp" #include <bits/stdc++.h> using namespace std; #include "../../String/SA_IS.cpp" int main() { string s; int q; cin >> s >> q; SA_IS sa = SA_IS(); auto v = sa.construct(s); for (int i = 0; i < q; ++i) { string t; cin >> t; if (sa.contain(s, t, v)) cout << 1 << endl; else cout << 0 << endl; } return 0; }
#line 1 "test/aoj/ALDS1_14_D.test.cpp" #define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ALDS1_14_D&lang=jp" #include <bits/stdc++.h> using namespace std; #line 1 "String/SA_IS.cpp" #line 5 "String/SA_IS.cpp" using namespace std; class SA_IS { public: SA_IS() {} vector<int> construct(string str) { vector<int> s(str.begin(), str.end()); return construct(s); } vector<int> construct(vector<int> s, const int k = 128) { if (s.size() <= 1) { return s.empty() ? (vector<int>){0} : (vector<int>){1, 0}; } s.push_back(0); vector<int> bkt(k, 0); vector<bool> is_stype(s.size()); // determine S-type or L-type for (int i = s.size() - 1; i >= 0; --i) { bkt[s[i]]++; is_stype[i] = (i + 1 == s.size()) || (s[i] < s[i + 1]) || (s[i] == s[i + 1] && is_stype[i + 1]); } for (int i = 1; i < k; ++i) bkt[i] += bkt[i - 1]; // Induced Sorting with wrong seed vector<int> b(bkt); vector<int> sa(s.size()), is_lms(s.size()); int lms_cnt = 0; for (int i = 1; i < s.size(); ++i) { if (!is_stype[i - 1] && is_stype[i]) { is_lms[i] = 1; sa[--bkt[s[i]]] = i; lms_cnt++; } } sa = inducedSort(s, sa, is_stype, b); int lms_substr = 1, pre = -1; is_lms[sa[0]] = lms_substr++; for (int i = 1; i < sa.size(); ++i) { if (!is_lms[sa[i]]) continue; if (pre >= 0 && s[pre] == s[sa[i]]) { int k; for (k = 1; s[pre + k] == s[sa[i] + k] && !is_lms[pre + k] && !is_lms[sa[i] + k]; ++k) ; lms_substr -= (s[pre + k] == s[sa[i] + k] && is_lms[pre + k] && is_lms[sa[i] + k]); } pre = sa[i]; is_lms[sa[i]] = lms_substr++; } vector<int> newstr(lms_cnt), rev(lms_cnt); int cnt = 0; for (int i = 0; i < s.size(); ++i) { if (!is_lms[i]) continue; newstr[cnt] = is_lms[i]; rev[cnt] = i; cnt++; } vector<int> sorted_lms = construct(newstr, lms_substr); sa.assign(s.size(), 0); for (int i = 1; i < sorted_lms.size(); ++i) { int j = rev[sorted_lms[i]]; sa[bkt[s[j]]++] = j; } return inducedSort(s, sa, is_stype, b); } vector<int> inducedSort(const vector<int>& s, const vector<int>&sa, const vector<bool>& is_stype, vector<int> bkt) { int n = sa.size(); vector<int> b(bkt), res(n); res[0] = sa[0]; for (int i = 0; i < n; ++i) { int j = sa[i] - 1, k = res[i] - 1; if (j >= 0 && !is_stype[j]) res[b[s[j] - 1]++] = j; else if (k >= 0 && !is_stype[k]) res[b[s[k] - 1]++] = k; } for (int i = n - 1; i >= 0; --i) { int j = res[i] - 1; if (j >= 0 && is_stype[j]) res[--bkt[s[j]]] = j; } return res; } bool contain(string s, string t, const vector<int>& sa) { int l = 0, r = sa.size(), m; while (r - l > 1) { m = (l + r) / 2; if (s.substr(sa[m], t.size()) <= t) l = m; else r = m; } return s.substr(sa[l], t.size()) == t; } }; #line 8 "test/aoj/ALDS1_14_D.test.cpp" int main() { string s; int q; cin >> s >> q; SA_IS sa = SA_IS(); auto v = sa.construct(s); for (int i = 0; i < q; ++i) { string t; cin >> t; if (sa.contain(s, t, v)) cout << 1 << endl; else cout << 0 << endl; } return 0; }