Matrix_code

strings - Suffix Automaton O(n)

May 3rd, 2016 (edited)
160
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.36 KB | None | 0 0
  1. /*******************************************************************************************
  2.                             Suffix Automaton
  3.     * A DAG in String Stores all Substring information
  4.     * Complexity : O(n)
  5.  
  6.     * len[v] -> Maximum length of the string accepted by state v
  7.     * link[v] -> Denotes a state which is a proper suffix of v and in different endpos class
  8.     * SIGMA -> # of different character
  9.     * # of substring accepted by a state = len[v] - len[link[v]]
  10.     * # of different substring = # of different paths in the DAG from root
  11.     * # of occurrence of a string which ends at p = # of paths from p to terminal nodes
  12.  
  13. *********************************************************************************************/
  14. #include<bits/stdc++.h>
  15. using namespace std;
  16. const int N = 25e4+5;
  17. const int SIGMA = 26;
  18. string A;
  19.  
  20. struct SAM {
  21.     int len[2*N], link[2*N];
  22.     int nxt[2*N][SIGMA];
  23.     int sz,last;
  24.     int SAT[2*N];
  25.     int cnt[2*N];
  26.     bool TerMinal[2*N];
  27.     int dp[2*N];
  28.     int toop[2*N];
  29.     void initTree()
  30.     {
  31.         last= 0;
  32.         len[last] = 0;
  33.         link[last] = -1;
  34.         sz = 1;
  35.         memset(nxt[0],0,sizeof nxt[0]);
  36.     }
  37.     void add(int c,int pos)
  38.     {
  39.         int cur = sz ++ , p = last; memset(nxt[cur],0,sizeof nxt[cur]);
  40.         len[cur] = 1 + len[last];
  41.         last = cur;
  42.         for(; p !=-1 && nxt[p][c] == 0; p = link[p] ) nxt[p][c] = cur;
  43.         if(p==-1) {
  44.             link[cur] = 0;
  45.         }
  46.         else {
  47.             int q = nxt[p][c];
  48.             if(len[q] == 1 + len[p] ) {
  49.                 link[cur] = q;
  50.             }
  51.             else {
  52.                 int clone = sz ++;
  53.                 memcpy(nxt[clone],nxt[q], sizeof(nxt[q]));
  54.                 len[clone] = 1 + len[p];
  55.                 link[clone] = link[q];
  56.                 link[q] = link[cur] = clone;
  57.                 for(; p !=-1 &&nxt[p][c]== q ; p = link[p]) nxt[p][c] = clone;
  58.             }
  59.         }
  60.         SAT[pos] = cur;
  61.     }
  62.     void Toop(int n) {
  63.         for (int i = 0; i <= n; i++) cnt[i] = 0;
  64.         for (int i = 1; i < sz; i++) cnt[len[i]]++;
  65.         for (int i = 1; i <= n; i++) cnt[i] += cnt[i - 1];
  66.         for (int i = 1; i < sz; i++) toop[cnt[len[i]]--] = i;
  67.     }
  68. }Solver;
  69. int main()
  70. {
  71.     Solver.initTree();
  72.     cin >> A;
  73.     for(int i = 0;i < A.length() ; i ++ ) {
  74.         Solver.add(A[i]-'A', i );
  75.     }
  76. }
Add Comment
Please, Sign In to add comment