Advertisement
pasholnahuy

Untitled

Sep 13th, 2023
702
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.78 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <algorithm>
  4. #include <queue>
  5.  
  6. using namespace std;
  7.  
  8. class Trie{
  9.     struct Node {
  10.         unordered_map<char, Node> next;
  11.         bool isTerminal = false;
  12.         Node* suf_ref = nullptr;
  13.         Node* terminal_ref = nullptr;
  14.         array<Node*, 26> go;
  15.         int num = 0;
  16.     }
  17.             root;
  18.     Node
  19.             *current = &root;
  20. public:
  21.     void Insert(const string& s, int num) {
  22.         Node* cur = &root;
  23.         for (auto c: s) {
  24.             cur = &cur->next[c];
  25.         }
  26.         cur->isTerminal = true;
  27.         cur->num = num;
  28.     }
  29.  
  30.     vector<int> Check(char c){
  31.         current = current->go[c - 'a'];
  32.         Node* temp = current;
  33.         vector<int> ans;
  34.         if (temp->isTerminal){
  35.             ans.emplace_back(temp->num);
  36.         }
  37.         while (temp->terminal_ref != &root){
  38.             temp = temp->terminal_ref;
  39.             ans.emplace_back(temp->num);
  40.         }
  41.         return ans;
  42.     }
  43.  
  44.     void Build(){
  45.         queue<Node*> q;
  46.         root.terminal_ref = &root;
  47.         root.suf_ref = &root;
  48.         q.push(&root);
  49.         while (!q.empty()){
  50.             auto cur = q.front();
  51.             cur->terminal_ref = cur->suf_ref->isTerminal ? cur->suf_ref: cur->suf_ref->terminal_ref;
  52.             q.pop();
  53.             for (auto& [letter, child]: cur->next){
  54.                 if (cur == &root){
  55.                     child.suf_ref = &root;
  56.                 } else {
  57.                     child.suf_ref = child.suf_ref->go[letter - 'a'];
  58.                 }
  59.                 q.push(&child);
  60.             }
  61.             if (!cur->isTerminal && cur->suf_ref->isTerminal){
  62.                 cur->isTerminal = true;
  63.             }
  64.             for (auto letter = 'a'; letter <= 'z'; ++letter){
  65.                 int ind = letter - 'a';
  66.                 if (cur->next.contains(letter)){
  67.                     cur->go[ind] = &cur->next[letter];
  68.                 } else if (cur != &root){
  69.                     cur->go[ind] = cur->suf_ref->go[ind];
  70.                 } else {
  71.                     cur->go[ind] = &root;
  72.                 }
  73.             }
  74.         }
  75.     }
  76. };
  77.  
  78. int main() {
  79.     Trie trie;
  80.     string s;
  81.     cin >> s;
  82.     int n;
  83.     cin >> n;
  84.     vector<string> vec;
  85.     vector<vector<int>> ans(n);
  86.     for (int i = 0; i < n; ++i){
  87.         string k;
  88.         cin >> k;
  89.         trie.Insert(k, i);
  90.         vec.emplace_back(k);
  91.     }
  92.     trie.Build();
  93.     for (int i = 0; i < s.size(); ++i){
  94.         for (auto el: trie.Check(s[i])){
  95.             ans[el].emplace_back(i);
  96.         }
  97.     }
  98.     for (int k = 0; k < ans.size(); ++k){
  99.         cout << ans[k].size() << " ";
  100.         for (auto ind: ans[k]){
  101.             cout << ind - vec[k].size() << " ";
  102.         }
  103.         cout << '\n';
  104.     }
  105.     return 0;
  106. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement