Guest User

Untitled

a guest
Jan 16th, 2025
249
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 10.45 KB | None | 0 0
  1. #ifdef _DEBUG
  2. #define _CRT_SECURE_NO_WARNINGS
  3. #endif
  4. #include <iostream>
  5. #include <fstream>
  6. #include <sstream>
  7. #include <climits>
  8. #include <iomanip>
  9. #include <cstdio>
  10. #include <vector>
  11. #include <string>
  12. #include <stack>
  13. #include <queue>
  14. #include <deque>
  15. #include <bitset>
  16. #include <algorithm>
  17. #include <cmath>
  18. #include <set>
  19. #include <unordered_set>
  20. #include <map>
  21. #include <unordered_map>
  22. #include <chrono>
  23. #include <random>
  24. #include <complex>
  25. #include <numeric>
  26. #include <assert.h>
  27.  
  28. using namespace std;
  29.  
  30. using ll = long long;
  31. using ull = unsigned long long;
  32. using ui = unsigned int;
  33. using ld = long double;
  34. using pii = pair<int, int>;
  35. using pil = pair<int, long long>;
  36. using pli = pair<long long, int>;
  37. using pll = pair<long long, long long>;
  38. template <typename T>
  39. using uset = unordered_set<T>;
  40. template <typename T1, typename T2>
  41. using umap = unordered_map<T1, T2>;
  42.  
  43. #define all(x) x.begin(), x.end()
  44. #define rall(x) x.rbegin(), x.rend()
  45.  
  46. #ifdef _DEBUG
  47. const int lg = 7;
  48. const int NODES = 100;
  49. const int N = 100;
  50. const int Q = 200;
  51. #else
  52. const int lg = 11;
  53. const int NODES = 1e6 + 200;
  54. const int N = 5e5 + 10 + 26;
  55. const int Q = 6e6 + 10;
  56. #endif
  57.  
  58. vector<int> g_sound[N];
  59. int used[N];
  60. int cmp[N];
  61.  
  62. void dfs(int v) {
  63.     used[v] = 1;
  64.     for (int u : g_sound[v])
  65.         if (!used[u]) {
  66.             cmp[u] = cmp[v];
  67.             dfs(u);
  68.         }
  69. }
  70.  
  71. struct node {
  72.     vector<int> ladder;
  73.     int to[26]{}, go[26]{};
  74.     int up[lg]{};
  75.     int par = 0, pch = 0, suf = 0, super = 0;
  76.     int dep = 0, len = 0, term = 0;
  77.     int mxd = 0;
  78. };
  79.  
  80. node trie[NODES];
  81. int hbit[NODES];
  82.  
  83. int get_term(int v) {
  84.     return trie[v].term ? v : trie[v].super;
  85. }
  86.  
  87. int LA(int v, int k) {
  88.     if (!k)
  89.         return v;
  90.     if (trie[v].dep <= k)
  91.         return 0;
  92.     int h = hbit[k];
  93.     v = trie[v].up[h];
  94.     k -= 1 << h;
  95.     int id = trie[trie[v].mxd].dep - trie[v].dep;
  96.     id += k;
  97.     return trie[trie[v].mxd].ladder[id];
  98. }
  99.  
  100. int nv = 1;
  101.  
  102. int ext() {
  103.     return nv++;
  104. }
  105.  
  106. void add(string &s, int x) {
  107.     int v = 0;
  108.     for (char cc : s) {
  109.         int c = cc - 'a';
  110.         if (!trie[v].to[c]) {
  111.             trie[nv].par = v;
  112.             trie[nv].pch = c;
  113.             trie[nv].len = trie[v].len + 1;
  114.             trie[v].to[c] = ext();
  115.         }
  116.         v = trie[v].to[c];
  117.     }
  118.     trie[v].term = x;
  119. }
  120.  
  121. void aho_corasick() {
  122.     vector<int> q(nv);
  123.     int tail = 0, head = 0;
  124.     q[tail++] = 0;
  125.     while (head < tail) {
  126.         int v = q[head++];
  127.         if (v && trie[v].par) {
  128.             trie[v].suf = trie[trie[trie[v].par].suf].go[trie[v].pch];
  129.             if (trie[trie[v].suf].term)
  130.                 trie[v].super = trie[v].suf;
  131.             else
  132.                 trie[v].super = trie[trie[v].suf].super;
  133.             trie[v].up[0] = trie[v].super;
  134.             trie[v].dep = trie[trie[v].super].dep;
  135.         }
  136.         if (trie[v].term) {
  137.             trie[v].dep++;
  138.             trie[v].up[0] = trie[v].super;
  139.         }
  140.         for (int c = 0; c < 26; c++) {
  141.             if (trie[v].to[c]) {
  142.                 trie[v].go[c] = trie[v].to[c];
  143.                 q[tail++] = trie[v].to[c];
  144.             } else {
  145.                 trie[v].go[c] = trie[trie[v].suf].go[c];
  146.             }
  147.         }
  148.     }
  149.     for (int i = nv - 1; i > -1; i--) {
  150.         int v = q[i];
  151.         if (!trie[v].mxd)
  152.             trie[v].mxd = v;
  153.         int dep = trie[trie[v].mxd].dep;
  154.         if (trie[v].term) {
  155.             trie[trie[v].mxd].ladder.push_back(v);
  156.             int pr1 = trie[v].super;
  157.             if (trie[trie[pr1].mxd].dep < dep)
  158.                 trie[pr1].mxd = trie[v].mxd;
  159.         }
  160.     }
  161.     for (int i = 1; i < lg; i++)
  162.         for (int j = 0; j < nv; j++)
  163.             if (trie[j].term)
  164.                 trie[j].up[i] = trie[trie[j].up[i - 1]].up[i - 1];
  165. }
  166.  
  167. const int mod1 = 1e9 + 7, mod2 = 1e9 + 9;
  168.  
  169. int add(int a, int b, int mod) {
  170.     if (a + b >= mod)
  171.         return a + b - mod;
  172.     return a + b;
  173. }
  174.  
  175. int sub(int a, int b, int mod) {
  176.     if (a < b)
  177.         return a - b + mod;
  178.     return a - b;
  179. }
  180.  
  181. int mul(int a, int b, int mod) {
  182.     return (ll)a * b % mod;
  183. }
  184.  
  185. const int base1 = 1e6 + 3, base2 = 1e6 + 23;
  186.  
  187. struct hint {
  188.     int h1 = 0, h2 = 0;
  189.  
  190.     hint() {}
  191.  
  192.     hint(int h) : h1(h), h2(h) {}
  193.  
  194.     hint(int h1, int h2) : h1(h1), h2(h2) {}
  195. };
  196.  
  197. hint operator+(const hint &a, const hint &b) {
  198.     return { add(a.h1, b.h1, mod1), add(a.h2, b.h2, mod2) };
  199. }
  200.  
  201. hint operator-(const hint &a, const hint &b) {
  202.     return { sub(a.h1, b.h1, mod1), sub(a.h2, b.h2, mod2) };
  203. }
  204.  
  205. hint operator*(const hint &a, const hint &b) {
  206.     return { mul(a.h1, b.h1, mod1), mul(a.h2, b.h2, mod2) };
  207. }
  208.  
  209. bool operator==(const hint &a, const hint &b) {
  210.     return a.h1 == b.h1 && a.h2 == b.h2;
  211. }
  212.  
  213. const hint base{ base1, base2 };
  214. hint pw[N];
  215.  
  216. struct query {
  217.     int l, r, i;
  218. };
  219.  
  220. string t;
  221.  
  222. pair<hint, int> hq[Q];
  223.  
  224. pair<hint, int> slow_dp[1000][1000];
  225.  
  226. vector<pii> del_edge[N];
  227.  
  228. int pr[N];
  229. pair<hint, int> dsu_hash[N];
  230. int jump[N];
  231. vector<pii> buc_q[N];
  232.  
  233. void compress(int a) {
  234.     if (pr[a] == a)
  235.         return;
  236.     compress(pr[a]);
  237.     dsu_hash[a].first = dsu_hash[a].first * pw[dsu_hash[pr[a]].second] + dsu_hash[pr[a]].first;
  238.     dsu_hash[a].second += dsu_hash[pr[a]].second;
  239.     pr[a] = pr[pr[a]];
  240. }
  241.  
  242. void divide(int l, int r, vector<query> q) {
  243.     if (q.empty())
  244.         return;
  245.     if (r - l <= 10) {
  246.         for (int ri = l; ri <= r - 2; ri++) {
  247.             int v = 0;
  248.             for (int li = ri; li >= l; li--) {
  249.                 v = trie[v].go[t[li] - 'a'];
  250.                 int u = get_term(v);
  251.                 if (trie[u].len == ri - li + 1)
  252.                     slow_dp[li - l][ri + 1 - l] = { trie[u].term, 1 };
  253.                 else {
  254.                     auto &tmp = slow_dp[li - l + trie[u].len][ri + 1 - l];
  255.                     slow_dp[li - l][ri - l + 1].first = hint(trie[u].term) * pw[tmp.second] + tmp.first;
  256.                     slow_dp[li - l][ri - l + 1].second = 1 + tmp.second;
  257.                 }
  258.             }
  259.         }
  260.         for (auto &qi : q) {
  261.             auto &tmp = slow_dp[qi.l - l][qi.r - l];
  262.             hq[qi.i].first = hq[qi.i].first * pw[tmp.second] + tmp.first;
  263.             hq[qi.i].second += tmp.second;
  264.         }
  265.         return;
  266.     }
  267.     int m = (l + r) / 2;
  268.     vector<query> ql, qr, tmp;
  269.     for (auto &qi : q) {
  270.         if (qi.r < m)
  271.             ql.push_back(qi);
  272.         else if (qi.l >= m)
  273.             qr.push_back(qi);
  274.         else
  275.             tmp.push_back(qi);
  276.     }
  277.     divide(l, m, ql);
  278.     ql.clear();
  279.     if (!tmp.empty()) {
  280.         for (int i = l; i < m; i++) {
  281.             pr[i] = i;
  282.             dsu_hash[i] = { 0, 0 };
  283.         }
  284.         for (int i = m; i < r; i++) {
  285.             del_edge[i].clear();
  286.             buc_q[i].clear();
  287.         }
  288.         for (auto &qi : tmp)
  289.             buc_q[qi.r].push_back({ qi.l, qi.i });
  290.         int v = 0, v1 = 0;
  291.         for (int i = r - 2; i >= m - 1; i--)
  292.             v1 = trie[v1].go[t[i] - 'a'];
  293.         jump[m - 1] = get_term(v1);
  294.         for (int i = m - 2; i >= l; i--) {
  295.             v = trie[v].go[t[i] - 'a'];
  296.             v1 = trie[v1].go[t[i] - 'a'];
  297.             int u = get_term(v), u1 = get_term(v1);
  298.             if (u == u1) {
  299.                 int j = i + trie[u].len;
  300.                 pr[i] = j;
  301.                 dsu_hash[i] = { trie[u].term, 1 };
  302.             } else {
  303.                 jump[i] = u1;
  304.                 u1 = LA(u1, trie[u1].dep - trie[u].dep - 1);
  305.                 int j = i + trie[u1].len;
  306.                 if (j > m)
  307.                     del_edge[j].push_back({ i, u });
  308.             }
  309.         }
  310.         for (int ri = r - 1; ri >= m; ri--) {
  311.             for (auto &qi : buc_q[ri]) {
  312.                 compress(qi.first);
  313.                 hint h = dsu_hash[qi.first].first;
  314.                 int len = dsu_hash[qi.first].second;
  315.                 int from = pr[qi.first];
  316.                 int u = jump[from];
  317.                 if (trie[u].len > ri - from) {
  318.                     for (int i = lg - 1; i > -1; i--)
  319.                         if (trie[trie[u].up[i]].len > ri - from)
  320.                             u = trie[u].up[i];
  321.                     u = trie[u].super;
  322.                 }
  323.                 int to = from + trie[u].len;
  324.                 h = h * base + trie[u].term;
  325.                 len++;
  326.                 hq[qi.second].first = hq[qi.second].first * pw[len] + h;
  327.                 hq[qi.second].second += len;
  328.                 if (to < ri)
  329.                     qr.push_back({ to, ri, qi.second });
  330.             }
  331.             for (auto &p : del_edge[ri]) {
  332.                 int i = p.first;
  333.                 int u = p.second;
  334.                 pr[i] = i + trie[u].len;
  335.                 dsu_hash[i] = { trie[u].term, 1 };
  336.             }
  337.         }
  338.     }
  339.     tmp.clear();
  340.     divide(m, r, qr);
  341. }
  342.  
  343. inline void solve() {
  344.     cin >> t;
  345.     int n, k;
  346.     cin >> n >> k;
  347.     vector<string> s(n + 26);
  348.     for (int i = 0; i < 26; i++)
  349.         s[i] = (char)(i + 'a');
  350.     for (int i = 0; i < n; i++) {
  351.         cin >> s[i + 26];
  352.         reverse(all(s[i + 26]));
  353.     }
  354.     for (int i = 0; i < k; i++) {
  355.         int v, u;
  356.         cin >> v >> u;
  357.         v--;
  358.         u--;
  359.         g_sound[v].push_back(u);
  360.         g_sound[u].push_back(v);
  361.     }
  362.     for (int v = 0; v < n + 26; v++)
  363.         if (!used[v]) {
  364.             cmp[v] = v + 1;
  365.             dfs(v);
  366.         }
  367.     for (int v = 0; v < n + 26; v++)
  368.         add(s[v], cmp[v]);
  369.     aho_corasick();
  370.     int queries;
  371.     cin >> queries;
  372.     vector<query> q(2 * queries);
  373.     for (int i = 0; i < queries; i++) {
  374.         int l1, r1, l2, r2;
  375.         cin >> l1 >> r1 >> l2 >> r2;
  376.         l1--;
  377.         l2--;
  378.         q[2 * i] = { l1, r1, 2 * i };
  379.         q[2 * i + 1] = { l2, r2, 2 * i + 1 };
  380.     }
  381.     divide(0, t.size() + 1, q);
  382.     for (int i = 0; i < 2 * queries; i += 2) {
  383.         if (hq[i] == hq[i + 1])
  384.             cout << "Yes\n";
  385.         else
  386.             cout << "No\n";
  387.     }
  388. }
  389.  
  390. signed main() {
  391.     for (int i = 2; i < NODES; i++)
  392.         hbit[i] = hbit[i >> 1] + 1;
  393.     pw[0] = { 1, 1 };
  394.     for (int i = 1; i < N; i++)
  395.         pw[i] = pw[i - 1] * base;
  396. #ifdef _DEBUG
  397.     freopen("01.dat", "r", stdin);
  398. #endif
  399.     ios_base::sync_with_stdio(false);
  400.     cin.tie(nullptr);
  401.     cout.tie(nullptr);
  402.     int tt = 1;
  403. #ifdef _DEBUG
  404.     cin >> tt;
  405. #endif
  406.     for (int test_id = 1; test_id <= tt; test_id++) {
  407. #ifdef _DEBUG
  408.         cout << "TESTCASE #" << test_id << ":\n";
  409. #endif
  410.         solve();
  411.     }
  412.     return 0;
  413. }
Advertisement
Add Comment
Please, Sign In to add comment