Guest User

Untitled

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