Friday, May 24, 2019

[Codechef] PALIN3 - 3 Palindromes

Author            : Dipu Kumar Mohanto 
                    CSE, Batch - 6
                    BRUR.
Problem Statement : PALIN3 - 3 Palindromes
Source            : Codechef
Category          : Data Structure
Algorithm         : Palindromic Tree
Verdict           : Accepted

  1. #include <bits/stdc++.h>  
  2.   
  3. using namespace std;  
  4.   
  5. #define ll              long long int  
  6.   
  7. static const int maxn = 1e6 + 5;  
  8.   
  9. struct Node  
  10. {  
  11.       int Next[10];  
  12.       int len;  
  13.       int sufflink;  
  14.       ll num;  
  15. };  
  16.   
  17. string s;  
  18. int len, suff, num;  
  19. Node Tree[maxn * 4];  
  20.   
  21. int cumsum[maxn];  
  22.   
  23. int isDivisible(int l, int r)  
  24. {  
  25.       int sze = r - l + 1;  
  26.       if (sze > 1 && s[l] == '0'return 0;  
  27.       int sum = cumsum[r];  
  28.       if (l-1 >= 0) sum -= cumsum[l-1];  
  29.       return (sum % 3 == 0);  
  30. }  
  31.   
  32. void init()  
  33. {  
  34.       num = 2; suff = 2;  
  35.       Tree[1].len = -1; Tree[1].sufflink = 1;  
  36.       Tree[2].len = 0; Tree[2].sufflink = 1;  
  37. }  
  38.   
  39. bool addLetter(int pos)  
  40. {  
  41.       int cur = suff, curlen = 0;  
  42.       int let = s[pos] - '0';  
  43.       while (true)  
  44.       {  
  45.             curlen = Tree[cur].len;  
  46.             if (pos - 1 - curlen >= 0 && s[pos - 1 - curlen] == s[pos]) break;  
  47.             cur = Tree[cur].sufflink;  
  48.       }  
  49.       if (Tree[cur].Next[let])  
  50.       {  
  51.             suff = Tree[cur].Next[let];  
  52.             return false;  
  53.       }  
  54.       num++;  
  55.       suff = num;  
  56.       Tree[num].len = Tree[cur].len + 2;  
  57.       Tree[cur].Next[let] = num;  
  58.       int add = isDivisible(pos - Tree[num].len + 1, pos);  
  59.       if (Tree[num].len == 1)  
  60.       {  
  61.             Tree[num].sufflink = 2;  
  62.             Tree[num].num = add;  
  63.             return true;  
  64.       }  
  65.       while (true)  
  66.       {  
  67.             cur = Tree[cur].sufflink;  
  68.             curlen = Tree[cur].len;  
  69.             if (pos - 1 - curlen >= 0 && s[pos - 1 - curlen] == s[pos])  
  70.             {  
  71.                   Tree[num].sufflink = Tree[cur].Next[let];  
  72.                   break;  
  73.             }  
  74.       }  
  75.       Tree[num].num = add + Tree[ Tree[num].sufflink ].num;  
  76.       return true;  
  77. }  
  78.   
  79. signed main()  
  80. {  
  81.       ios_base::sync_with_stdio(false);  
  82.       cin.tie(nullptr);  
  83.       cout.tie(nullptr);  
  84.       cout << fixed << setprecision(3);  
  85.   
  86.       #ifndef ONLINE_JUDGE  
  87.             freopen("in.txt""r", stdin);  
  88.       #endif // ONLINE_JUDGE  
  89.   
  90.       cin >> s;  
  91.       len = s.size();  
  92.   
  93.       cumsum[0] = s[0] - '0';  
  94.       for (int i = 1; i < len; i++) cumsum[i] = (s[i] - '0') + cumsum[i-1];  
  95.   
  96.       init();  
  97.       ll ans = 0;  
  98.       for (int i = 0; i < len; i++)  
  99.       {  
  100.             addLetter(i);  
  101.             ans += Tree[suff].num;  
  102.       }  
  103.       cout << ans << '\n';  
  104.   
  105. }  

No comments:

Post a Comment

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