Manioc

suffix automata

Oct 22nd, 2017
130
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 1.13 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4.  
  5. struct state{
  6.     int len, link;
  7.     map<int,int> next;
  8. };
  9.  
  10. state st[2*360];
  11. int sz,last;
  12.  
  13. void sa_init(){
  14.     sz = 1;
  15.     last = 0;
  16.     st[0].len = 0;
  17.     st[0].link = -1;
  18.     st[0].next.clear();
  19. }
  20.  
  21. void sa_extend(int c){
  22.     int cur = sz++;
  23.     st[cur].len = st[last].len + 1;
  24.     st[cur].next.clear();
  25.     int p;
  26.     for(p = last; p != -1 && !st[p].next.count(c); p = st[p].link) st[p].next[c] = cur;
  27.  
  28.     if(p == -1) st[cur].link = 0;
  29.     else{
  30.         int q = st[p].next[c];
  31.         if(st[p].len + 1 == st[q].len) st[cur].link = q;
  32.         else{
  33.             int clone = sz++;
  34.             st[clone].len = st[p].len + 1;
  35.             st[clone].next = st[q].next;
  36.             st[clone].link = st[q].link;
  37.             for(; p!= -1 && st[p].next[c] == q; p = st[p].link) st[p].next[c] = clone;
  38.             st[q].link = st[cur].link = clone; 
  39.         }
  40.     }  
  41.     last = cur;
  42. }
  43.  
  44. long long conta_substring(){
  45.     long long ret = 0;
  46.     for(int i = 1; i < sz; i++) ret += st[i].len - st[st[i].link].len;
  47.     return ret;
  48. }
  49.  
  50. int main(){
  51.     sa_init();
  52.     string palavra;
  53.     cin >> palavra;
  54.     for(int i = 0; i < palavra.size(); i++) sa_extend(palavra[i]);
  55.     cout << conta_substring << endl;
  56.     return 0;
  57. }
Advertisement
Add Comment
Please, Sign In to add comment