Monday, December 10, 2018

[toph.co] Bomb Disposal Strings

Author            : Dipu Kumar Mohanto 
                    CSE, Batch - 6
                    BRUR.
Problem Statement : Bomb Disposal Strings
Source            : toph.co
Category          : Data Structure, String
Algorithm         : Z Algorithm, Palindromic Tree
Verdict           : Accepted
  1. #include "bits/stdc++.h"  
  2.    
  3. using namespace std;  
  4.    
  5. const int maxn = 3000000;  
  6.    
  7. int Z[maxn];  
  8. string string1, string2;  
  9.    
  10. void Z_ALGO(string s)  
  11. {  
  12.     fill(begin(Z), end(Z), 0);  
  13.     int len = s.size();  
  14.     Z[0] = len;  
  15.     int lt = 0, rt = 0;  
  16.     for (int k = 1; k < len; k++)  
  17.     {  
  18.         if (k > rt)  
  19.         {  
  20.             int n = 0;  
  21.             while (n+k < len && s[n] == s[n+k])  
  22.             {  
  23.                 n++;  
  24.             }  
  25.             Z[k] = n;  
  26.             if (n > 0)  
  27.             {  
  28.                 lt = k;  
  29.                 rt = k+n-1;  
  30.             }  
  31.         }  
  32.         else  
  33.         {  
  34.             int p = k - lt;  
  35.             int right_part_len = rt - k + 1;  
  36.             if (Z[p] < right_part_len)  
  37.             {  
  38.                 Z[k] = Z[p];  
  39.             }  
  40.             else  
  41.             {  
  42.                 int i = rt + 1;  
  43.                 while (i < len && s[i] == s[i-k])  
  44.                 {  
  45.                     i++;  
  46.                 }  
  47.                 Z[k] = i - k;  
  48.                 lt = k;  
  49.                 rt = i-1;  
  50.             }  
  51.         }  
  52.     }  
  53. }  
  54.    
  55.    
  56. string final_string(string s1, string s2)  
  57. {  
  58.     int sze_s1 = s1.size();  
  59.     int sze_s2 = s2.size();  
  60.     string final;   // required string  
  61.     Z_ALGO(s2);  
  62.     int maxLen = 0;  
  63.     for (int i = 1; i < sze_s2; i++)  
  64.         maxLen = max(maxLen, Z[i]);  
  65.     if (maxLen == 0)  
  66.     {  
  67.         final = s1 + s2;  
  68.         return final;  
  69.     }  
  70.     string concate = "";  
  71.     for (int i = 0; i < maxLen; i++)  
  72.         concate += s2[i];  
  73.     concate += "$";  
  74.     concate += s1;  
  75.     int sze_concate = concate.size();  
  76.     Z_ALGO(concate);  
  77.     bool ok = false;  
  78.     for (int i = maxLen+1; i < sze_concate; i++)  
  79.         if (maxLen == Z[i])  
  80.             ok = true;  
  81.     if (!ok)  
  82.     {  
  83.         final = s1 + s2;  
  84.         return final;  
  85.     }  
  86.     final = s1;  
  87.     for (int i = maxLen; i < sze_s2; i++)  
  88.         final += s2[i];  
  89.     return final;  
  90. }  
  91.    
  92.    
  93. struct node  
  94. {  
  95.     int next[27];  
  96.     int len;  
  97.     int sufflink;  
  98.     long long num;  
  99. };  
  100.    
  101. int len;  
  102. string s;  
  103. node tree[maxn];  
  104. int  num;            // node 1 - root with len -1, node 2 - root with len 0  
  105. int suff;            // max suffix palindrome  
  106. long long ans;  
  107.    
  108. bool addLetter(int pos)  
  109. {  
  110.     int cur = suff, curlen = 0;  
  111.     int let = s[pos] - 'a';  
  112.     while (true)  
  113.     {  
  114.         curlen = tree[cur].len;  
  115.         if (pos - 1 - curlen >= 0 && s[pos - 1 - curlen] == s[pos])  
  116.             break;  
  117.         cur = tree[cur].sufflink;  
  118.     }  
  119.     if (tree[cur].next[let])  
  120.     {  
  121.         suff = tree[cur].next[let];  
  122.         return false;  
  123.     }  
  124.     num++;  
  125.     suff = num;  
  126.     tree[num].len = tree[cur].len + 2;  
  127.     tree[cur].next[let] = num;  
  128.     if (tree[num].len == 1)  
  129.     {  
  130.         tree[num].sufflink = 2;  
  131.         tree[num].num = 1;  
  132.         return true;  
  133.     }  
  134.     while (true)  
  135.     {  
  136.         cur = tree[cur].sufflink;  
  137.         curlen = tree[cur].len;  
  138.         if (pos - 1 - curlen >= 0 && s[pos - 1 - curlen] == s[pos])  
  139.         {  
  140.             tree[num].sufflink = tree[cur].next[let];  
  141.             break;  
  142.         }  
  143.     }  
  144.     tree[num].num = 1 + tree[tree[num].sufflink].num;  
  145.     return true;  
  146. }  
  147.    
  148. void initTree()  
  149. {  
  150.     num = 2; suff = 2;  
  151.     tree[1].len = -1; tree[1].sufflink = 1;  
  152.     tree[2].len = 0; tree[2].sufflink = 1;  
  153. }  
  154.    
  155. int main()  
  156. {  
  157.     //freopen("in.txt", "r", stdin);  
  158.    
  159.     ios_base::sync_with_stdio(false);  
  160.     cin.tie(NULL);  
  161.     cout.tie(NULL);  
  162.    
  163.     cin >> string1 >> string2;  
  164.     string ss = final_string(string2, string1);  
  165.     string sss = final_string(string1, string2);  
  166.     int len1 = ss.size();  
  167.     int len2 = sss.size();  
  168.     s = (len1 < len2) || (len1==len2 && ss < sss) ? ss : sss;  
  169.     len = s.size();  
  170.     initTree();  
  171.     for (int i = 0; i < len; i++) {  
  172.         addLetter(i);  
  173.         ans += tree[suff].num;  
  174.     }  
  175.     cout << ans << endl;  
  176.     return 0;  
  177. }  
  178.    

No comments:

Post a Comment

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