Friday, December 14, 2018

[UVa Live Archive] 3451 - Longest Common Substring

Author            : Dipu Kumar Mohanto 
                    CSE, Batch - 6
                    BRUR.
Problem Statement : 3451 - Longest Common Substring
Source            : UVa Live Archive
Category          : String
Algorithm         : Suffix Automaton
Verdict           : Accepted 
Problem Type : Longest Common Substring of Multiple string.
               Array Implemetation.
  1. #include <bits/stdc++.h>  
  2.    
  3. using namespace std;  
  4.    
  5.    
  6. const int inf = 1 << 28;  
  7. const int mx = 1e5+5;  
  8.    
  9. struct state   
  10. {  
  11.     int len;  
  12.     int link;  
  13.     int w;  
  14.     int v;   
  15.     map <charint> next;  
  16. } st[mx << 1];  
  17.    
  18. int sz, last;  
  19.    
  20. void init()  
  21. {  
  22.     last = sz = 0;  
  23.     st[0].len = 0;  
  24.     st[0].link = -1;  
  25.     st[0].w = inf;  
  26.     st[0].v = 0;  
  27.     for (int i = 0; i < (mx << 1); i++) st[i].next.clear();  
  28.     ++sz;  
  29. }  
  30.    
  31. void sz_extend(char c)  
  32. {  
  33.     int curr = sz++;  
  34.     st[curr].len = st[last].len + 1;  
  35.     st[curr].w = inf;  
  36.     int p;  
  37.     for (p = last; p != -1 && !st[p].next.count(c); p = st[p].link)  
  38.         st[p].next[c] = curr;  
  39.     if (p == -1)  
  40.         st[curr].link = 0;  
  41.     else  
  42.     {  
  43.         int q = st[p].next[c];  
  44.         if (st[p].len + 1 == st[q].len)  
  45.             st[curr].link = q;  
  46.         else  
  47.         {  
  48.             int clone = sz++;  
  49.             st[clone].len = st[p].len + 1;  
  50.             st[clone].link = st[q].link;  
  51.             st[clone].next = st[q].next;  
  52.             st[clone].w = inf;  
  53.             for (; p != -1 && st[p].next[c] == q; p = st[p].link)  
  54.                 st[p].next[c] = clone;  
  55.             st[q].link = st[curr].link = clone;  
  56.         }  
  57.     }  
  58.     last = curr;  
  59. }  
  60.    
  61. int tNode;  
  62.    
  63. void buildDFA(string s, int len)  
  64. {  
  65.     init();  
  66.     for (int f = 0; f < len; f++) sz_extend(s[f]);  
  67.     tNode = sz;  
  68. }  
  69.    
  70. void LCS(string t, int len)  
  71. {  
  72.     int v = 0;  
  73.     int l = 0;  
  74.     for (int i = 0; i < len; i++)  
  75.     {  
  76.         char c = t[i];  
  77.         while (v && !st[v].next.count(c))  
  78.         {  
  79.             v = st[v].link;  
  80.             l = st[v].len;  
  81.         }  
  82.         if (st[v].next.count(c))  
  83.         {  
  84.             v = st[v].next[c];  
  85.             l++;  
  86.         }  
  87.         st[v].v = max(st[v].v, l);  
  88.     }  
  89.     for (int i=1; i<tNode; i++)  
  90.         st[st[i].link].v = max(st[st[i].link].v, st[i].v);  
  91.     for (int i=0; i<tNode; i++)  
  92.     {  
  93.         st[i].w = min(st[i].w, st[i].v);  
  94.         st[i].v = 0;  
  95.     }  
  96. }  
  97.    
  98. string arr[32];  
  99. int arr_len[32];  
  100.    
  101. int main()  
  102. {  
  103.     //freopen("in.txt", "r", stdin);  
  104.    
  105.     ios::sync_with_stdio(false);  
  106.     cin.tie(nullptr);  
  107.    
  108.     int n;  
  109.     while (cin >> n)  
  110.     {  
  111.         int m = 0;  
  112.         for (int index=0; index<n; index++)  
  113.         {  
  114.             cin >> arr[index];  
  115.             arr_len[index] = arr[index].length();  
  116.             if (arr_len[index] > arr_len[m]) m = index;  
  117.         }  
  118.         buildDFA(arr[m], arr_len[m]);  
  119.         for (int i = 0; i < n; i++)  
  120.         {  
  121.             if (i == m)  
  122.                 continue;  
  123.             LCS(arr[i], arr_len[i]);  
  124.         }  
  125.         int res = -1;  
  126.         for (int i=0; i<tNode; i++)  
  127.         {  
  128.             res = max(res, min(st[i].len, st[i].w));  
  129.         }  
  130.         cout << res << endl;  
  131.     }  
  132.     return 0;  
  133. }  

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.