Advertisement
kulmak41

Untitled

Nov 28th, 2021
1,097
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.60 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2.  
  3. #define ssize(a) (int)(a).size()
  4. #define all(a) (a).begin(), (a).end()
  5.  
  6. using namespace std;
  7.  
  8. using ll = long long;
  9.  
  10. const int max_len = 1e5 + 10;
  11. char text[max_len];
  12. int p[max_len];
  13. int np[max_len];
  14. int c[max_len];
  15. int nc[max_len];
  16. int cnt[max_len];
  17. int text_len = 0;
  18.  
  19. const int max_queries = 15740785;
  20. char query_s[max_queries];
  21. int query_begin[max_queries];
  22. int prefix_len[max_queries];
  23. int query_len = 0;
  24. int queries_cnt = 0;
  25.  
  26. void build_sa() {
  27.     int n = text_len;
  28.  
  29.     iota(p, p + n, 0);
  30.     sort(p, p + n, [&](int i, int j) {
  31.         return text[i] < text[j];
  32.     });
  33.     c[p[0]] = 0;
  34.     for (int i = 1; i < n; ++i) {
  35.         c[p[i]] = c[p[i - 1]] + (text[p[i]] != text[p[i - 1]]);
  36.     }
  37.     for (int k = 1; c[p[n - 1]] < n - 1; k *= 2) {
  38.         for (int i = 0; i < n; ++i) {
  39.             np[i] = p[i] - k;
  40.             if (np[i] < 0)
  41.                 np[i] += n;
  42.         }
  43.         memset(cnt, 0, sizeof cnt);
  44.         for (int i = 0; i < n; ++i) {
  45.             ++cnt[c[i]];
  46.         }
  47.         for (int i = 1; i < n; ++i) {
  48.             cnt[i] += cnt[i - 1];
  49.         }
  50.         for (int i = n - 1; i >= 0; --i) {
  51.             p[--cnt[c[np[i]]]] = np[i];
  52.         }
  53.  
  54.         nc[p[0]] = 0;
  55.         for (int i = 1; i < n; ++i) {
  56.             nc[p[i]] = nc[p[i - 1]];
  57.             if (c[p[i]] != c[p[i - 1]]) {
  58.                 ++nc[p[i]];
  59.             } else {
  60.                 int x = p[i - 1] + k;
  61.                 if (x > n)
  62.                     x -= n;
  63.                 int y = p[i] + k;
  64.                 if (y > n)
  65.                     y -= n;
  66.                 if (c[x] != c[y])
  67.                     ++nc[p[i]];
  68.             }
  69.         }
  70.         memcpy(c, nc, sizeof c);
  71.     }
  72. }
  73.  
  74.  
  75. const int max_log = 18;
  76. int st[max_log][max_len];
  77.  
  78. void build_st() {
  79.     int n = text_len;
  80.     int logn = __lg(n);
  81.     for (int i = 0; i < n; ++i) {
  82.         st[0][i] = p[i];
  83.     }
  84.     for (int k = 1; k <= logn; ++k) {
  85.         for (int i = 0; i + (1 << k) <= n; ++i) {
  86.             st[k][i] = min(st[k - 1][i], st[k - 1][i + (1 << (k - 1))]);
  87.         }
  88.     }
  89. }
  90.  
  91. int get_min(int l, int r) {
  92.     int k = __lg(r - l);
  93.     return min(st[k][l], st[k][r - (1 << k)]);
  94. }
  95.  
  96. int main() {
  97.     ios_base::sync_with_stdio(false);
  98.     cin.tie(nullptr);
  99.     freopen("nenokku.in", "r", stdin);
  100.  
  101.     {
  102.         char t;
  103.         string s;
  104.         while (cin >> t >> s) {
  105.             for (auto& c : s) {
  106.                 c = tolower(c);
  107.             }
  108.             if (t == 'A') {
  109.                 for (auto& c : s) {
  110.                     text[text_len++] = c;
  111.                 }
  112.             } else {
  113.                 query_begin[queries_cnt] = query_len;
  114.                 prefix_len[queries_cnt] = text_len;
  115.                 ++queries_cnt;
  116.                 for (auto& c : s) {
  117.                     query_s[query_len++] = c;
  118.                 }
  119.             }
  120.         }
  121.     }
  122.  
  123.     text[text_len++] = '#';
  124.  
  125.     build_sa();
  126.     build_st();
  127.  
  128.     for (int i = 0; i < queries_cnt; ++i) {
  129.         int end = (i == queries_cnt - 1 ? query_len : query_begin[i + 1]);
  130.         string s(query_s + query_begin[i], query_s + end);
  131.         int s_len = end - query_begin[i];
  132.  
  133.         int l, r;
  134.  
  135.         int low = 0;
  136.         int high = text_len + 1;
  137.         int low_lcp = 0;
  138.         int high_lcp = 0;
  139.         while (high - low > 1) {
  140.             int mid = (low + high) >> 1;
  141.             int k = min(low_lcp, high_lcp);
  142.             int suf = p[mid];
  143.             while (k < s_len && text[suf + k] == s[k])
  144.                 ++k;
  145.             if (k == s_len || text[suf + k] > s[k])
  146.                 high = mid, high_lcp = k;
  147.             else
  148.                 low = mid, low_lcp = k;
  149.         }
  150.  
  151.         l = high;
  152.  
  153.         if (high_lcp < s_len) {
  154.             cout << "NO\n";
  155.             continue;
  156.         }
  157.  
  158.         low = l - 1;
  159.         high = text_len + 1;
  160.         low_lcp = 0;
  161.         high_lcp = 0;
  162.         while (high - low > 1) {
  163.             int mid = (low + high) >> 1;
  164.             int k = min(low_lcp, high_lcp);
  165.             int suf = p[mid];
  166.             while (k < s_len && text[suf + k] == s[k])
  167.                 ++k;
  168.             if (k < s_len && text[suf + k] > s[k])
  169.                 high = mid, high_lcp = k;
  170.             else
  171.                 low = mid, low_lcp = k;
  172.         }
  173.  
  174.         r = high;
  175.  
  176.         if (l == r) {
  177.             cout << "NO\n";
  178.         } else {
  179.             int mn = get_min(l, r);
  180.             if (mn + s_len - 1 < prefix_len[i]) {
  181.                 cout << "YES\n";
  182.             } else {
  183.                 cout << "NO\n";
  184.             }
  185.         }
  186.     }
  187.  
  188.     return 0;
  189. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement