Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- #define ssize(a) (int)(a).size()
- #define all(a) (a).begin(), (a).end()
- using namespace std;
- using ll = long long;
- vector<int> suf_arr(string s) {
- s.push_back('#');
- int n = ssize(s);
- vector<int> p(n);
- vector<int> np(n);
- vector<int> c(n);
- vector<int> nc(n);
- vector<int> cnt(n);
- iota(all(p), 0);
- sort(all(p), [&](int i, int j) {
- return s[i] < s[j];
- });
- c[p[0]] = 0;
- for (int i = 1; i < n; ++i) {
- c[p[i]] = c[p[i - 1]] + (s[p[i]] != s[p[i - 1]]);
- }
- for (int k = 1; c[p[n - 1]] < n - 1; k *= 2) {
- for (int i = 0; i < n; ++i) {
- np[i] = p[i] - k;
- if (np[i] < 0)
- np[i] += n;
- }
- fill(all(cnt), 0);
- for (int x : c) {
- ++cnt[x];
- }
- for (int i = 1; i < n; ++i) {
- cnt[i] += cnt[i - 1];
- }
- for (int i = n - 1; i >= 0; --i) {
- p[--cnt[c[np[i]]]] = np[i];
- }
- nc[p[0]] = 0;
- for (int i = 1; i < n; ++i) {
- nc[p[i]] = nc[p[i - 1]];
- if (c[p[i]] != c[p[i - 1]]) {
- ++nc[p[i]];
- } else {
- int x = p[i - 1] + k;
- if (x > n)
- x -= n;
- int y = p[i] + k;
- if (y > n)
- y -= n;
- if (c[x] != c[y])
- ++nc[p[i]];
- }
- }
- c.swap(nc);
- }
- p.erase(p.begin());
- return p;
- }
- struct Sparse {
- vector<vector<int>> st;
- Sparse(vector<int>& a) {
- int n = ssize(a);
- int logn = __lg(n);
- st.resize(logn + 1, vector<int>(n));
- st[0] = a;
- for (int k = 1; k <= logn; ++k) {
- for (int i = 0; i + (1 << k) <= n; ++i) {
- st[k][i] = min(st[k - 1][i], st[k - 1][i + (1 << (k - 1))]);
- }
- }
- }
- int get(int l, int r) {
- int k = __lg(r - l);
- return min(st[k][l], st[k][r - (1 << k)]);
- }
- };
- int main() {
- #ifdef LOCAL
- freopen("input.txt", "r", stdin);
- #endif
- ios_base::sync_with_stdio(false);
- cin.tie(nullptr);
- string text;
- vector<int> prefix_len;
- vector<string> ask_s;
- {
- char t;
- string s;
- while (cin >> t >> s) {
- for (auto& c : s) {
- c = tolower(c);
- }
- if (t == 'A') {
- text += s;
- } else {
- prefix_len.push_back(ssize(text));
- ask_s.push_back(s);
- }
- }
- }
- vector<int> sa = suf_arr(text);
- Sparse st(sa);
- // for (int i = 0; i < ssize(text); ++i) {
- // cout << i << " " << text.substr(sa[i]) << "\n";
- // }
- for (int i = 0; i < ssize(ask_s); ++i) {
- int l = partition_point(all(sa), [&](int j) {
- int k = min(ssize(text), j + ssize(ask_s[i]));
- return lexicographical_compare(text.begin() + j, text.begin() + k, all(ask_s[i]));
- }) - sa.begin();
- int r = partition_point(sa.begin() + l, sa.end(), [&](int j) {
- int k = min(ssize(text), j + ssize(ask_s[i]));
- return !lexicographical_compare(all(ask_s[i]), text.begin() + j, text.begin() + k);
- }) - sa.begin();
- // cout << l << " " << r << " ";
- if (l == r) {
- cout << "NO";
- } else {
- int mn = st.get(l, r);
- if (mn + ssize(ask_s[i]) - 1 < prefix_len[i]) {
- cout << "YES";
- } else {
- cout << "NO";
- }
- }
- cout << "\n";
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement