Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #define _CRT_SECURE_NO_WARNINGS
- #define _USE_MATH_DEFINES
- #pragma GCC optimize("unroll-loops")
- #pragma GCC optimize("fast-math")
- #pragma optimize("O3")
- #include <iostream>
- #include <string>
- #include <vector>
- #include <fstream>
- #include <bitset>
- #include <iomanip>
- #include <math.h>
- #include <stdlib.h>
- #include <map>
- #include <unordered_map>
- #include <tuple>
- #include <cmath>
- #include <functional>
- #include <cassert>
- #include <algorithm>
- #include <set>
- #include <deque>
- #include <numeric>
- using namespace std;
- #define kekek ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0)
- const int maxL = 1e6 + 3;
- const int alpha = 'z' - 'a' + 1;
- struct node {
- int suff, p, supersuff, move[alpha], go[alpha];
- char c;
- vector<int> term;
- node(int par, int ch) {
- suff = supersuff = -1;
- c = ch;
- p = par;
- for (int i = 0; i < alpha; i++) {
- move[i] = -1;
- go[i] = -1;
- }
- }
- node() {
- c = p = suff = supersuff = -1;
- for (int i = 0; i < alpha; i++) {
- move[i] = -1;
- go[i] = -1;
- }
- }
- };
- int sz = 1;
- node trie[maxL];
- vector<vector<int>> ans;
- void add(string& s, int num) {
- int v = 0, n = s.size();
- for (int i = 0; i < n; i++) {
- if (trie[v].move[s[i] - 'a'] == -1) {
- trie[sz].suff = trie[sz].supersuff = -1;
- for (int i = 0; i < alpha; i++) {
- trie[sz].move[i] = -1;
- trie[sz].go[i] = -1;
- }
- trie[v].move[s[i] - 'a'] = sz;
- trie[sz].p = v;
- trie[sz].c = s[i] - 'a';
- sz++;
- }
- v = trie[v].move[s[i] - 'a'];
- }
- trie[v].term.emplace_back(num);
- }
- int go(int u, char c);
- int getsuff(int u) {
- if (trie[u].suff == -1) {
- if (trie[u].p == 0) {
- trie[u].suff = 0;
- }
- else {
- return go(getsuff(trie[u].p), trie[u].c);
- }
- }
- return trie[u].suff;
- }
- int go(int u, char c) {
- if (trie[u].go[c] == -1) {
- if (trie[u].move[c] != -1) {
- trie[u].go[c] = trie[u].move[c];
- }
- else {
- if (u != 0) {
- trie[u].go[c] = go(getsuff(u), c);
- }
- else {
- trie[u].go[c] = 0;
- }
- }
- }
- return trie[u].go[c];
- }
- int supersuff(int u) {
- if (trie[u].supersuff == -1) {
- if (!trie[getsuff(u)].term.empty()) {
- trie[u].supersuff = getsuff(u);
- }
- else {
- trie[u].supersuff = supersuff(getsuff(u));
- }
- }
- return trie[u].supersuff;
- }
- void dfs(int v, int pos) {
- if (v == 0) return;
- if (trie[v].term.size()) {
- for (auto i : trie[v].term) {
- ans[i].emplace_back(pos);
- }
- }
- dfs(supersuff(v), pos);
- }
- signed main() {
- kekek;
- node root(0, -1);
- root.suff = 0;
- root.term.push_back(-1);
- root.supersuff = 0;
- trie[0] = root;
- string t;
- cin >> t;
- int n;
- cin >> n;
- string *kek = new string[n];
- for (int i = 0; i < n; i++) {
- cin >> kek[i];
- add(kek[i], i);
- }
- ans.resize(n + 1);
- int v = 0;
- for (int i = 0; i < t.size(); i++) {
- v = go(v, t[i] - 'a');
- dfs(v, i + 1);
- }
- for (int i = 0; i < n; i++) {
- cout << ans[i].size() << ' ';
- for (auto j : ans[i]) {
- cout << j - kek[i].size() + 1 << " ";
- }
- cout << '\n';
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement