Monday, December 10, 2018

[toph.co] Password Decryption

Author            : Dipu Kumar Mohanto 
                    CSE, Batch - 6
                    BRUR.
Problem Statement : Password Decryption
Source            : toph.co
Category          : Data Structure
Algorithm         : Palindromic Tree
Verdict           : Accepted

  1. #include "bits/stdc++.h"  
  2.    
  3. using namespace std;  
  4.    
  5. static const int maxn = 105000;  
  6.    
  7. struct node  
  8. {  
  9.       int next[26];  
  10.       int len;  
  11.       int sufflink;  
  12.       int num;  
  13. } tree[maxn];  
  14.    
  15. int len;  
  16. string s;  
  17. int num;  
  18. int suff;  
  19.    
  20. int maxVowel, maxLen;  
  21.    
  22. int cntVowel[maxn];  
  23. int lengthPal[maxn], blockInd[maxn];  
  24.    
  25. inline bool addLetter(int pos)  
  26. {  
  27.       int curr = suff;  
  28.       int currlen = 0;  
  29.       int let = s[pos] - 'a';  
  30.       while (true)  
  31.       {  
  32.             currlen = tree[curr].len;  
  33.             if (pos-1-currlen >= 0 && s[pos-1-currlen] == s[pos]) break;  
  34.             curr = tree[curr].sufflink;  
  35.       }  
  36.       if (tree[curr].next[let])  
  37.       {  
  38.             suff = tree[curr].next[let];  
  39.             return false;  
  40.       }  
  41.       num++;  
  42.       suff = num;  
  43.       tree[num].len = tree[curr].len + 2;  
  44.       tree[curr].next[let] = num;  
  45.       int length = tree[num].len;  
  46.       int start = pos - length + 1;  
  47.       int tVowel = cntVowel[pos] - (start>0 ? cntVowel[start-1] : 0);  
  48.       if (tVowel <= maxVowel)  
  49.       {  
  50.             lengthPal[start] = length;  
  51.             maxLen = max(maxLen, length);  
  52.       }  
  53.       if (tree[num].len == 1)  
  54.       {  
  55.             tree[num].sufflink = 2;  
  56.             tree[num].num = 1;  
  57.             return true;  
  58.       }  
  59.       while (true)  
  60.       {  
  61.             curr = tree[curr].sufflink;  
  62.             currlen = tree[curr].len;  
  63.             if (pos-1-currlen >= 0 && s[pos-1-currlen] == s[pos])  
  64.             {  
  65.                   tree[num].sufflink = tree[curr].next[let];  
  66.                   break;  
  67.             }  
  68.       }  
  69.       tree[num].num = 1 + tree[tree[num].sufflink].num;  
  70.       return true;  
  71. }  
  72.    
  73. inline void initialize()  
  74. {  
  75.       num = 2;  
  76.       suff = 2;  
  77.       tree[1].len = -1, tree[1].sufflink = 1;  
  78.       tree[2].len = 0, tree[2].sufflink = 1;  
  79.       for (int i = 0; i < maxn; i++)  
  80.       {  
  81.             memset(tree[i].next, 0, sizeof tree[i].next);  
  82.       }  
  83. }  
  84.    
  85. int main()  
  86. {  
  87.       //freopen("in.txt", "r", stdin);  
  88.       ios_base::sync_with_stdio(false);  
  89.       cin.tie(NULL);  
  90.       cout.tie(NULL);  
  91.    
  92.       int tc;  
  93.       cin >> tc;  
  94.       for (int tcase = 1; tcase <= tc; tcase++)  
  95.       {  
  96.             cin >> len >> maxVowel;  
  97.             cin >> s;  
  98.             initialize();  
  99.             fill(begin(cntVowel), end(cntVowel), 0);  
  100.             fill(begin(lengthPal), end(lengthPal), 0);  
  101.             fill(begin(blockInd), end(blockInd), 0);  
  102.             maxLen = 0;  
  103.             for (int i = 0; i < len; i++)  
  104.             {  
  105.                   if (i > 0) cntVowel[i] = cntVowel[i-1];  
  106.                   if (s[i]=='a' || s[i]=='e' || s[i]=='i' || s[i]=='o' || s[i]=='u') cntVowel[i]++;  
  107.                   addLetter(i);  
  108.             }  
  109.             cout << "Case " << tcase << ": ";  
  110.             if (maxLen == 0)  
  111.             {  
  112.                   cout << "not found\n";  
  113.                   continue;  
  114.             }  
  115.             vector <int> vec;  
  116.             for (int i = 0; i < len; i++)  
  117.             {  
  118.                   if (lengthPal[i] == maxLen)  
  119.                   {  
  120.                         vec.push_back(i);  
  121.                   }  
  122.             }  
  123.             string ans = "";  
  124.             int add = 0;  
  125.             while (true)  
  126.             {  
  127.                   char minc;  
  128.                   bool f = false;  
  129.                   if (add >= maxLen) break;  
  130.                   for (int i : vec)   
  131.                   {  
  132.                         int ii = i + add;  
  133.                         if (blockInd[i] == 1) continue;  
  134.                         if (f == false)  
  135.                         {  
  136.                               minc = s[ii];  
  137.                               f = true;  
  138.                         }  
  139.                         else  
  140.                         {  
  141.                               minc = min(minc, s[ii]);  
  142.                         }  
  143.                   }  
  144.                   for (int i : vec)  
  145.                   {  
  146.                         int ii = i + add;  
  147.                         if (blockInd[i] == 1) continue;  
  148.                         if (s[ii] > minc) blockInd[i] = 1;  
  149.                   }  
  150.                   add++;  
  151.             }  
  152.             for (int i : vec)  
  153.             {  
  154.                   if (blockInd[i] == 0)  
  155.                   {  
  156.                         for (int j = 0, k = i; j < maxLen; j++, k++)  
  157.                         {  
  158.                               ans += s[k];  
  159.                         }  
  160.                         break;  
  161.                   }  
  162.             }  
  163.             cout << ans << "\n";  
  164.       }  
  165. }  

No comments:

Post a Comment

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