knightL

Suffix Tree

Oct 24th, 2020 (edited)
307
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.81 KB | None | 0 0
  1. #include<iostream>
  2. #include<vector>
  3. #include<cstdio>
  4. #include<map>
  5. #include<cstring>
  6. #include<string>
  7. using namespace std;
  8. int MAXN = 100100;
  9. class position
  10. {
  11. public:
  12.     position(int v, int l): v(v), l(l) {}
  13.     int v, l;
  14. };
  15.  
  16. class node
  17. {
  18. public:
  19.     node(int l, int r, int par): l(l), r(r), par(par), link(-1){}
  20.     node(): r(MAXN), link(-1){}
  21.     int l, r, par, link;
  22.     map<char, int> next;
  23. };
  24. int szt;
  25. int szs;
  26. char s[100100];
  27. node suffTree[200200];
  28.  
  29.  
  30. int link(int v);
  31.  
  32.  
  33. int leng(int v)
  34. {
  35.     return suffTree[v].r-suffTree[v].l;
  36. }
  37.  
  38. int addToParent(int l, int r, int par)
  39. {
  40.     int nid= szt++;
  41.     suffTree[nid] = node(l, r, par);
  42.     return suffTree[par].next[s[l]] = nid;
  43. }
  44.  
  45. int splitEdge(position pos)
  46. {
  47.     int v = pos.v;
  48.     int up = pos.l;
  49.     int down = leng(v)-up;
  50.     if(up == 0) return v;
  51.     if(down == 0) return suffTree[v].par;//return par;
  52.     int mid = addToParent(suffTree[v].l, suffTree[v].l+down, suffTree[v].par);
  53.     suffTree[v].l += down;
  54.     suffTree[v].par = mid;
  55.     suffTree[mid].next[s[suffTree[v].l]] = v;
  56.     return mid;
  57. }
  58.  
  59. position readChar(position pos, char c)
  60. {
  61.     int v = pos.v;
  62.     int up = pos.l;
  63.     if(up)
  64.         return s[suffTree[v].r-up]==c?position(v,up-1):position(-1,-1);
  65.     else
  66.     {
  67.         int w = suffTree[v].next.find(c)!=suffTree[v].next.end()?suffTree[v].next[c]:-1;
  68.         return w!=-1?position(w, leng(w)-1):position(-1,-1);
  69.     }
  70. }
  71.  
  72. position addChar(position pos, int i)
  73. {
  74.     while(true)
  75.     {
  76.         position npos = readChar(pos, s[i]);
  77.         if(npos.v != -1)
  78.             return npos;
  79.         else
  80.         {
  81.             int mid = splitEdge(pos);
  82.             addToParent(i, MAXN, mid);
  83.             pos = position(link(mid), 0);
  84.             if(mid == 0) return pos;
  85.         }
  86.     }
  87. }
  88.  
  89. position goDownFast(int v, int l, int r)
  90. {
  91.     if(l == r) return position(v, 0);
  92.     while(true)
  93.     {
  94.         v = suffTree[v].next[s[l]];
  95.         if(leng(v) >= r-l) return position(v, leng(v)-r+l);
  96.         l += leng(v);
  97.     }
  98. }
  99.  
  100. int link(int v)
  101. {
  102.     if(suffTree[v].link == -1)
  103.         suffTree[v].link = splitEdge(goDownFast(link(suffTree[v].par), suffTree[v].l+(suffTree[v].par==0), suffTree[v].r));
  104.     return suffTree[v].link;
  105. }
  106.  
  107. void makesuffTree()
  108. {
  109.     szt = 1;
  110.     node root(-1, -1, -1);
  111.     root.link = 0;
  112.     suffTree[0] = root;
  113.     position pos(0, 0);
  114.     for(int i = 0; i < szs; i++)
  115.         pos = addChar(pos, i);
  116. }
  117.  
  118. vector<int> vid;
  119. vector<int> par;
  120. vector<int> l;
  121. vector<int> r;
  122. void print(node &n, int nid)
  123. {
  124.     vid.push_back(nid);
  125.     par.push_back(n.par);
  126.      l .push_back(n. l );
  127.      r .push_back(n. r==MAXN?szs:n.r );
  128.      for(map<char, int>::iterator it = n.next.begin(); it != n.next.end(); it++)
  129.          print(suffTree[it->second],it->second);
  130. }
  131. int ord[200200];
  132. int main()
  133. {
  134.     scanf("%s", s);
  135.     szs = strlen(s);
  136.     makesuffTree();
  137.     print(suffTree[0],0);
  138.  
  139.     cout << par.size() << endl;
  140.     ord[vid[0]]=0;
  141.     for(int i = 1; i < par.size(); i++)
  142.     {
  143.         printf("%d %d %d\n", ord[par[i]], l[i], r[i]);
  144.         ord[vid[i]]=i;
  145.     }
  146.  
  147.  
  148.     return 0;
  149. }
Add Comment
Please, Sign In to add comment