Advertisement
Guest User

Untitled

a guest
Apr 6th, 2020
183
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.15 KB | None | 0 0
  1. #include <iostream>
  2. #include <algorithm>
  3. #include <vector>
  4. #include <cmath>
  5. #include <climits>
  6. #include <unordered_set>
  7. #include <set>
  8. #include <map>
  9. #include <iomanip>
  10. #include <cstdlib>
  11. #include <string>
  12. #include <cstring>
  13. #include <fstream>
  14. #include <cstdio>
  15. #include <sstream>
  16. #include <clocale>
  17.  
  18. using namespace std;
  19. string s;
  20.  
  21. struct vertex {
  22.     struct edge {
  23.         int l, siz;
  24.         vertex* to;
  25.         edge(int l = 0, int siz = 0, vertex* to = nullptr) : l(l), siz(siz), to(to) {}
  26.     };
  27.     vertex* par;
  28.     char par_c;
  29.     set<int> num_suf;
  30.     map<char, edge> links;
  31.     map<char, vertex*> pref_links;
  32.     vertex(vertex* par = nullptr) : par(par) {}
  33. };
  34.  
  35. void dfs(vertex* t) {
  36.     if (!t->num_suf.empty())
  37.         return;
  38.     for (auto el : t->links) {
  39.         dfs(el.second.to);
  40.         for (auto el2 : el.second.to->num_suf)
  41.             t->num_suf.insert(el2);
  42.     }
  43. }
  44.  
  45. void build(string& s, vertex* t) {
  46.     vertex* fictive = new vertex();
  47.     for (char i = 'A'; i < 'z'; i++) {
  48.         fictive->pref_links[i] = t;
  49.         fictive->links[i] = vertex::edge(0, 1, t);
  50.     }
  51.     t->par_c = 'A';
  52.     t->par = fictive;
  53.     fictive->pref_links['$'] = t;
  54.     s.push_back('$');
  55.     int n = s.length();
  56.     vertex* last_vertex = t;
  57.     vector<vertex*> stack;
  58.     stack.reserve(n);
  59.     for (int i = n - 1; i > -1; i--) {
  60.         if (i == 1)
  61.             s[i] = s[i];
  62.         int now_height = n - i;
  63.         while (!last_vertex->pref_links.count(s[i])) {
  64.             stack.push_back(last_vertex);
  65.             now_height -= last_vertex->par->links[last_vertex->par_c].siz;
  66.             last_vertex = last_vertex->par;
  67.         }      
  68.         vertex* w = last_vertex->pref_links[s[i]];
  69.         int to_split = 0;
  70.         if (!w->links.count(s[i + now_height])) {
  71.             vertex* tmp = new vertex(w);
  72.             tmp->par_c = s[i + now_height];
  73.             w->links[s[i + now_height]] = vertex::edge(i + now_height, n - i - now_height, tmp);
  74.             stack[0]->pref_links[s[i]] = tmp;
  75.             tmp->num_suf.insert(i);
  76.             last_vertex = tmp;
  77.             stack.clear();
  78.             continue;
  79.         }
  80.         //if ((stack.back())->par_c == '$')
  81.         //  stack.pop_back();
  82.         vertex::edge u = w->links[s[i + now_height]];
  83.         vertex* last = nullptr;
  84.         int a = 0;
  85.         for (; !stack.empty() && s[i + now_height] == s[u.l + to_split];) {
  86.             a = (stack.back())->par->links[(stack.back())->par_c].siz;
  87.             to_split += a;
  88.             now_height += a;
  89.             last = stack.back();
  90.             stack.pop_back();
  91.         }
  92.         stack.push_back(last);
  93.         if (to_split == 0) {
  94.             vertex* tmp = new vertex(w);
  95.             tmp->par_c = s[i + now_height];
  96.             w->links[s[i + now_height]] = vertex::edge(i + now_height, n - i - now_height, tmp);
  97.             if (!stack.empty())
  98.                 stack[0]->pref_links[s[i]] = tmp;
  99.             tmp->num_suf.insert(i);
  100.             last_vertex = tmp;
  101.         }
  102.         else {
  103.             vertex* tmp = new vertex(w);
  104.             vertex* tmp2 = new vertex(w);
  105.             tmp2->links[s[u.l + to_split]] = vertex::edge(u.l + to_split, w->links[s[u.l]].siz - to_split, u.to);
  106.             u.to->par = tmp2;
  107.             u.to->par_c = s[u.l + to_split];
  108.             w->links[s[u.l]].siz = to_split;
  109.             w->links[s[u.l]].to = tmp2;
  110.             tmp2->par_c = s[u.l];
  111.             tmp2->links[s[i + now_height]] = vertex::edge(i + now_height, (n - i) - now_height, tmp);
  112.             tmp->par_c = s[i + now_height];
  113.             tmp->par = tmp2;
  114.             tmp->num_suf.insert(i);
  115.             (stack.back())->pref_links[s[i]] = tmp2;
  116.             stack[0]->pref_links[s[i]] = tmp;
  117.             last_vertex = tmp;
  118.         }
  119.         stack.clear();
  120.     }
  121.     dfs(t);
  122. }
  123.  
  124. set<int> finds(const string& s2, vertex* t) {
  125.     set<int> ans;
  126.     int it = 0;
  127.     vertex* now_t = t;
  128.     bool found = false;
  129.     while (it < s2.length()) {
  130.         if (!now_t->links.count(s2[it]))
  131.             return set<int>();
  132.         char c = s2[it];
  133.         int siz = now_t->links[c].siz, l = now_t->links[c].l;
  134.         for (int i = l; i < l + siz; i++) {
  135.             if (s2[it++] != s[i]) {
  136.                 return set<int>();
  137.             }
  138.             if (it >= s2.length()) {
  139.                 found = true;
  140.                 break;
  141.             }
  142.         }
  143.         now_t = now_t->links[c].to;
  144.         if (found)
  145.             break;
  146.     }
  147.     return now_t->num_suf;
  148. }
  149.  
  150. signed main() {
  151.     vertex* t = new vertex();
  152.     //cin >> s;
  153.     s = "mississippi";
  154.     build(s, t);
  155.     t;
  156.     string s2;
  157.     cin >> s2;
  158.     set<int> ans = finds(s2, t);
  159.     for (auto el : ans)
  160.         cout << el << ' ';
  161.     return 0;
  162. }
  163. /*#include <iostream>
  164. #include <algorithm>
  165. #include <string>
  166. #include <map>
  167.  
  168. using namespace std;
  169.  
  170. const int MAXLEN = 600000;
  171. string s;
  172. int pos[MAXLEN], len[MAXLEN], par[MAXLEN];
  173. map<char, int> to[MAXLEN], link[MAXLEN];
  174. int sz = 2;
  175. int path[MAXLEN];
  176.  
  177. void attach(int child, int parent, char c, int child_len)
  178. {
  179.     to[parent][c] = child;
  180.     len[child] = child_len;
  181.     par[child] = parent;
  182. }
  183.  
  184. void extend(int i)
  185. {
  186.     int v, vlen = s.size() - i, old = sz - 1, pstk = 0;
  187.     for (v = old; !link[v].count(s[i]); v = par[v]) {
  188.         vlen -= len[v];
  189.         path[pstk++] = v;
  190.     }
  191.     int w = link[v][s[i]];
  192.     if (to[w].count(s[i + vlen])) {
  193.         int u = to[w][s[i + vlen]];
  194.         for (pos[sz] = pos[u] - len[u]; s[pos[sz]] == s[i + vlen]; pos[sz] += len[v]) {
  195.             v = path[--pstk];
  196.             vlen += len[v];
  197.         }
  198.         attach(sz, w, s[pos[u] - len[u]], len[u] - (pos[u] - pos[sz]));
  199.         attach(u, sz, s[pos[sz]], pos[u] - pos[sz]);
  200.         w = link[v][s[i]] = sz++;
  201.     }
  202.     link[old][s[i]] = sz;
  203.     attach(sz, w, s[i + vlen], s.size() - (i + vlen));
  204.     pos[sz++] = s.size();
  205. }
  206.  
  207. int main() {
  208.     len[1] = 1; pos[1] = 0; par[1] = 0;
  209.     for (int c = 0; c < 256; c++)
  210.         link[0][c] = 1;
  211.     s = "mississippi$";
  212.     for (int i = s.size() - 1; i >= 0; i--)
  213.         extend(i);
  214. }*/
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement