Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <vector>
- #include <algorithm>
- #include <queue>
- using namespace std;
- class Trie{
- struct Node {
- unordered_map<char, Node> next;
- bool isTerminal = false;
- Node* suf_ref = nullptr;
- Node* terminal_ref = nullptr;
- array<Node*, 26> go;
- int num = 0;
- }
- root;
- Node
- *current = &root;
- public:
- void Insert(const string& s, int num) {
- Node* cur = &root;
- for (auto c: s) {
- cur = &cur->next[c];
- }
- cur->isTerminal = true;
- cur->num = num;
- }
- vector<int> Check(char c){
- current = current->go[c - 'a'];
- Node* temp = current;
- vector<int> ans;
- if (temp->isTerminal){
- ans.emplace_back(temp->num);
- }
- while (temp->terminal_ref != &root){
- temp = temp->terminal_ref;
- ans.emplace_back(temp->num);
- }
- return ans;
- }
- void Build(){
- queue<Node*> q;
- root.terminal_ref = &root;
- root.suf_ref = &root;
- q.push(&root);
- while (!q.empty()){
- auto cur = q.front();
- cur->terminal_ref = cur->suf_ref->isTerminal ? cur->suf_ref: cur->suf_ref->terminal_ref;
- q.pop();
- for (auto& [letter, child]: cur->next){
- if (cur == &root){
- child.suf_ref = &root;
- } else {
- child.suf_ref = cur->suf_ref->go[letter - 'a'];
- }
- q.push(&child);
- }
- if (!cur->isTerminal && cur->suf_ref->isTerminal){
- cur->isTerminal = true;
- }
- for (auto letter = 'a'; letter <= 'z'; ++letter){
- int ind = letter - 'a';
- if (cur->next.contains(letter)){
- cur->go[ind] = &cur->next[letter];
- } else if (cur != &root){
- cur->go[ind] = cur->suf_ref->go[ind];
- } else {
- cur->go[ind] = &root;
- }
- }
- }
- }
- };
- int main() {
- Trie trie;
- string s;
- cin >> s;
- int n;
- cin >> n;
- vector<string> vec;
- vector<vector<int>> ans(n);
- for (int i = 0; i < n; ++i){
- string k;
- cin >> k;
- trie.Insert(k, i);
- vec.emplace_back(k);
- }
- trie.Build();
- for (int i = 0; i < s.size(); ++i){
- for (auto el: trie.Check(s[i])){
- ans[el].emplace_back(i);
- }
- }
- for (int k = 0; k < ans.size(); ++k){
- cout << ans[k].size() << " ";
- for (auto ind: ans[k]){
- cout << ind - vec[k].size() + 2 << " ";
- }
- cout << '\n';
- }
- return 0;
- };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement