Guest User

Untitled

a guest
Jul 22nd, 2018
76
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.56 KB | None | 0 0
  1. #include <fstream>
  2.  
  3. using namespace std;
  4.  
  5. char NUL = 'a' - 1;
  6. int SIZE = 'z' - 'a' + 2;
  7.  
  8.  
  9. struct Item
  10. {
  11.     int left;
  12.     int right;
  13.     Item *parent;
  14.     Item **children;
  15.     Item *suffix;
  16.  
  17.     int num;
  18.  
  19.     Item(int l = -1, int r = -1, Item *p = NULL)
  20.     {
  21.         left = l;
  22.         right = r;
  23.         parent = p;
  24.         children = new Item* [SIZE];
  25.         for (int i = 0; i < SIZE; i++)
  26.         {
  27.             children[i] = NULL;
  28.         }
  29.     }
  30. };
  31.  
  32. struct Position
  33. {
  34.     Item *vertex;
  35.     int shift;
  36.    
  37.     Position(Item *v, int s)
  38.     {
  39.         vertex = v;
  40.         shift = s; 
  41.     }
  42. };
  43.  
  44. Item *last;
  45. Item *root = new Item(-1, -1, NULL);
  46.  
  47. String s;
  48.  
  49.  
  50. void add(Position *position, int l, int r)
  51. {
  52.     if (position->shift == 0)
  53.     {
  54.         position->vertex->children[s[i] - NUL] = new Item(l, r, position->vertex);
  55.         last = position->vertex->children[s[l] - NUL];
  56.     }
  57.     else
  58.     {
  59.         Item *temp = new Item(position->vertex->left, position->vertex->right - position->shift, position->vertex->parent);
  60.         position->vertex->left = position->vertex->right - position->shift + 1;
  61.         position->vertex->parent = temp;
  62.         temp->parent->children[s[temp->left] - NUL] = temp;
  63.         temp->children[s[position->vertex->left] - NUL] = position->vertex;
  64.  
  65.         temp->children[s[l] - NUL] = new Item(l, r, temp);
  66.  
  67.         last = temp->children[s[l] - NUL];
  68.     }
  69. }
  70.  
  71. void jump(Position *pos, int pretailL, int pretailR)
  72. {
  73.     while (pretailR - pretailL >= 0)
  74.     {
  75.         pos->vertex = pos->vertex->children[s[pretailL] - NUL];
  76.         pos->shift = pos->vertex->right - pos->vertex->left + 1;
  77.         if (pretailL + pos->shift <= pretailR + 1)
  78.         {
  79.             pretailL += pos->shift;
  80.             pos->shift = 0;
  81.  
  82.         }
  83.         else
  84.         {
  85.             pos->shift -= pretailR - pretailL + 1;
  86.             pretailL = pretailR + 1;
  87.         }
  88.     }
  89. }
  90.  
  91. int go(Position *pos, int tailL, int tailR)
  92. {
  93.     while (tailR - tailL >= 0)
  94.     {
  95.         if (pos->shift == 0)
  96.         {
  97.             if (pos->vertex->children[s[tailL] - NUL] == NULL)
  98.             {
  99.                 return tailL;
  100.             }
  101.             else
  102.             {
  103.                 pos->vertex = pos->vertex->children[s[tailL] - NUL];
  104.                 pos->shift = pos->vertex->right - pos->vertex->left + 1;
  105.             }
  106.         }
  107.  
  108.         if (s[tailL] == s[pos->vertex->right - pos->shift + 1])
  109.         {
  110.             tailL++;
  111.             pos->shift--;
  112.         }
  113.         else
  114.         {
  115.             return tailL;
  116.         }
  117.     }
  118.     return tailL;
  119. }
  120.  
  121. long long countSubstrings(Item *vertex)
  122. {
  123.     long long res = 0;
  124.     for (int i = 1; i < SIZE; i++)
  125.     {
  126.         if (vertex->children[i] != NULL)
  127.         {
  128.             res += countSubstrings(vertex->children[i]);
  129.             res += vertex->children[i]->right - vertex->children[i]->left + 1;
  130.             if (s[vertex->children[i]->right] == NUL)
  131.             {
  132.                 res--;
  133.             }
  134.         }
  135.     }
  136.     return res;
  137. }
  138.  
  139. void addSuf(int i)
  140. {
  141.     if (last == NULL)
  142.     {
  143.         add(new Position(root, 0), i, s->length() - 1);
  144.     }
  145.     else
  146.     {
  147.         Item *father = last->parent;
  148.         int tailL = last->left;
  149.         int tailR = last->right;
  150.  
  151.         if (father == root)
  152.         {
  153.             tailL++;
  154.             Position *pos = new Position(father, 0);
  155.             tailL = go(pos, tailL, tailR);
  156.             add(pos, tailL, tailR);
  157.         }
  158.         else
  159.         {
  160.             Item *ver = father->parent;
  161.             int pretailL = father->left;
  162.             int pretailR = father->right;
  163.             Position *pos = new Position(ver->suffix, 0);
  164.             if (ver == root)
  165.             {
  166.                 pretailL++;
  167.             }
  168.             jump(pos, pretailL, pretailR);
  169.  
  170.             if (pos->shift == 0)
  171.             {
  172.                 father->suffix = pos->vertex;
  173.             }
  174.  
  175.             tailL = go(pos, tailL, tailR);
  176.             add(pos, tailL, tailR);
  177.  
  178.             if (father->suffix == NULL)
  179.             {
  180.                 father->suffix = last->parent;
  181.             }
  182.         }
  183.     }
  184. }
  185.  
  186. int main()
  187. {
  188.     std::ifstream input("count.in");
  189.     std::ofstream output("count.out");
  190.  
  191.     input >> s;
  192.     roof->suffix = root;
  193.  
  194.     for (int i = 0; i < s.length(); i++)
  195.     {
  196.         addSuf(i);
  197.     }
  198.  
  199.     output << countSubstrings(root);
  200. }
Add Comment
Please, Sign In to add comment