Saturday, November 23, 2019

[Codeforces] D. Match & Catch

Author            : Dipu Kumar Mohanto 
                    CSE, Batch - 6
                    BRUR.
Problem Statement : D. Match & Catch
Source            : Codeforces
Category          : String
Algorithm         : Suffix Tree
Verdict           : Accepted

  1. #include "bits/stdc++.h"  
  2.   
  3. using namespace std;  
  4.   
  5. static const int maxn = 1e6 + 5;  
  6. static const int inf  = 1e9 + 5;  
  7.   
  8.   
  9. struct Node  
  10. {  
  11.       int l;  
  12.       int r;  
  13.       int par;  
  14.       int link;  
  15.       map <char,int> next;  
  16.       Node(int l = 0, int r = 0, int par = -1)  
  17.             : l(l)  
  18.             , r(r)  
  19.             , par(par)  
  20.             , link(-1) {}  
  21.   
  22.       int len()  
  23.       {  
  24.             return r - l;  
  25.       }  
  26.       int &get(char c)  
  27.       {  
  28.             if (!next.count(c)) next[c] = -1;  
  29.             return next[c];  
  30.       }  
  31. };  
  32.   
  33. Node t[maxn];  
  34. string s;  
  35. int sz;  
  36. int n;  
  37.   
  38. struct state  
  39. {  
  40.       int v, pos;  
  41.       state(int v, int pos) : v(v), pos(pos) {}  
  42. };  
  43.   
  44. state ptr (0, 0);  
  45.   
  46. state go(state st, int l, int r)  
  47. {  
  48.       while (l < r)  
  49.       {  
  50.             if (st.pos == t[st.v].len())  
  51.             {  
  52.                   st = state (t[st.v].get( s[l] ), 0);  
  53.                   if (st.v == -1) return st;  
  54.             }  
  55.             else  
  56.             {  
  57.                   if (s[ t[st.v].l + st.pos ] != s[l])  
  58.                         return state (-1, -1);  
  59.                   if (r - l < t[st.v].len() - st.pos)  
  60.                         return state (st.v, st.pos + r-l);  
  61.                   l += t[st.v].len() - st.pos;  
  62.                   st.pos = t[st.v].len();  
  63.             }  
  64.       }  
  65.       return st;  
  66. }  
  67.   
  68. int split(state st)  
  69. {  
  70.       if (st.pos == t[st.v].len())  
  71.             return st.v;  
  72.       if (st.pos == 0)  
  73.             return t[st.v].par;  
  74.       Node v = t[st.v];  
  75.       int id = sz++;  
  76.       t[id] = Node(v.l, v.l + st.pos, v.par);  
  77.       t[v.par].get(s[v.l]) = id;  
  78.       t[id].get(s[v.l + st.pos]) = st.v;  
  79.       t[st.v].par = id;  
  80.       t[st.v].l += st.pos;  
  81.       return id;  
  82. }  
  83.   
  84. int get_link(int v)  
  85. {  
  86.       if (t[v].link != -1)  
  87.             return t[v].link;  
  88.       if (t[v].par == -1)  
  89.             return 0;  
  90.       int to = get_link(t[v].par);  
  91.       return t[v].link = split(go(state(to, t[to].len()), t[v].l + (t[v].par == 0), t[v].r));  
  92. }  
  93.   
  94. void tree_extend(int pos)  
  95. {  
  96.       for(;;)  
  97.       {  
  98.             state nptr = go(ptr, pos, pos+1);  
  99.             if (nptr.v != -1)  
  100.             {  
  101.                   ptr = nptr;  
  102.                   return;  
  103.             }  
  104.             int mid = split(ptr);  
  105.             int leaf = sz++;  
  106.             t[leaf] = Node(pos, n, mid);  
  107.             t[mid].get(s[pos]) = leaf;  
  108.             ptr.v = get_link(mid);  
  109.             ptr.pos = t[ptr.v].len();  
  110.             if (!mid) break;  
  111.       }  
  112. }  
  113.   
  114. void build_tree()  
  115. {  
  116.       sz = 1;  
  117.       for (int i = 0; i < n; i++)  
  118.             tree_extend(i);  
  119. }  
  120.   
  121. string s1;  
  122. string s2;  
  123. int len1;  
  124. int len2;  
  125.   
  126. int dfs(int u = 0, int p = -1)  
  127. {  
  128.       int mini = inf;  
  129.       vector <int> go;  
  130.       for (auto it : t[u].next)  
  131.       {  
  132.             char ch = it.first;  
  133.             int v = it.second;  
  134.             if (v == p) continue;  
  135.             go.push_back(v);  
  136.       }  
  137.       int len = go.size();  
  138.       if (len < 2) return mini;  
  139.       if (len == 2)  
  140.       {  
  141.             int pos1 = t[ go[0] ].l;  
  142.             int pos2 = t[ go[1] ].l;  
  143.             if (pos1 > pos2) swap(pos1, pos2);  
  144.             if (t[ go[0] ].r == n && t[ go[1] ].r == n)  
  145.             {  
  146.                   if (pos1 <= len1 and pos2 > len1) return 1;  
  147.                   return mini;  
  148.             }  
  149.       }  
  150.       for (int v : go)  
  151.       {  
  152.             mini = min(mini, t[u].len() + dfs(v, u));  
  153.       }  
  154.       return mini;  
  155. }  
  156.   
  157. signed main()  
  158. {  
  159.       ios_base::sync_with_stdio(false);  
  160.       cin.tie(nullptr);  
  161.       cout.tie(nullptr);  
  162.   
  163.       #ifndef ONLINE_JUDGE  
  164.             freopen("in.txt""r", stdin);  
  165.       #endif // ONLINE_JUDGE  
  166.   
  167.       cin >> s1 >> s2;  
  168.       len1 = s1.size();  
  169.       len2 = s2.size();  
  170.       s = s1 + "#" + s2 + "$";  
  171.       n = s.size();  
  172.       build_tree();  
  173.       int ans = dfs();  
  174.       if (ans == inf) ans = -1;  
  175.       cout << ans;  
  176. }