Friday, December 14, 2018

[UVa] 12833 - Daily Potato

Author            : Dipu Kumar Mohanto 
                    CSE, Batch - 6
                    BRUR.
Problem Statement : 12833 - Daily Potato
Source            : UVa Online Judge
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 segmentTree  
  8. {  
  9.     int arr[26];  
  10.     void assignLeaf(int val)  
  11.     {  
  12.         fill(begin(arr), end(arr), 0);  
  13.         arr[val] = 1;  
  14.     }  
  15.     void marge(segmentTree &l, segmentTree &r)  
  16.     {  
  17.         for (int i = 0; i < 26; i++) arr[i] = l.arr[i] + r.arr[i];  
  18.     }  
  19. } Tree[maxn << 2];  
  20.   
  21. char s[maxn];  
  22. char qs[maxn];  
  23.   
  24. inline void build(int node, int a, int b)  
  25. {  
  26.     if (a == b)  
  27.     {  
  28.         Tree[node].assignLeaf(s[a] - 'a');  
  29.         return;  
  30.     }  
  31.     int lft = node << 1;  
  32.     int rgt = lft | 1;  
  33.     int mid = (a + b) >> 1;  
  34.     build(lft, a, mid);  
  35.     build(rgt, mid+1, b);  
  36.     Tree[node].marge(Tree[lft], Tree[rgt]);  
  37. }  
  38.   
  39. inline int query(int node, int a, int b, int i, int j, int val)  
  40. {  
  41.     if (a > b || a > j || b < i) return 0;  
  42.     if (a >= i && b <= j) return Tree[node].arr[val];  
  43.     int lft = node << 1;  
  44.     int rgt = lft | 1;  
  45.     int mid = (a + b) >> 1;  
  46.     int p1 = query(lft, a, mid, i, j, val);  
  47.     int p2 = query(rgt, mid+1, b, i, j, val);  
  48.     return p1+p2;  
  49. }  
  50.   
  51. struct node  
  52. {  
  53.     int next[26];  
  54.     int len;  
  55.     int sufflink;  
  56.     int pos;  
  57.     vector <int> backlink;  
  58.     int extraBacklink;  
  59. } tree[maxn];  
  60.   
  61. int len;  
  62. int num;  
  63. int suff;  
  64. int ans[26][maxn];  
  65.   
  66. inline bool addLetter(int pos)  
  67. {  
  68.     int cur = suff;  
  69.     int curlen = 0;  
  70.     int let = s[pos] - 'a';  
  71.     while (true)  
  72.     {  
  73.         curlen = tree[cur].len;  
  74.         if (pos-1-curlen >= 0 && s[pos-1-curlen] == s[pos]) break;  
  75.         cur = tree[cur].sufflink;  
  76.     }  
  77.     if (tree[cur].next[let])  
  78.     {  
  79.         suff = tree[cur].next[let];  
  80.         tree[suff].extraBacklink += 1;  
  81.         return false;  
  82.     }  
  83.     num++;  
  84.     suff = num;  
  85.     tree[num].len = tree[cur].len + 2;  
  86.     tree[num].pos = pos;  
  87.     tree[cur].next[let] = num;  
  88.     if (tree[num].len == 1)  
  89.     {  
  90.         tree[num].sufflink = 2;  
  91.         return true;  
  92.     }  
  93.     while (true)  
  94.     {  
  95.         cur = tree[cur].sufflink;  
  96.         curlen = tree[cur].len;  
  97.         if (pos-1-curlen >= 0 && s[pos-1-curlen] == s[pos])  
  98.         {  
  99.             tree[num].sufflink = tree[cur].next[let];  
  100.             tree[tree[cur].next[let]].backlink.push_back(num);  
  101.             break;  
  102.         }  
  103.     }  
  104.     return true;  
  105. }  
  106.   
  107. inline void initTree()  
  108. {  
  109.     num = 2;  
  110.     suff = 2;  
  111.     tree[1].len = -1;  
  112.     tree[1].sufflink = 1;  
  113.     tree[2].len = 0;  
  114.     tree[2].sufflink = 1;  
  115.     for (int i = 0; i < maxn; i++)  
  116.     {  
  117.         fill(begin(tree[i].next), end(tree[i].next), 0);  
  118.         tree[i].backlink.clear();  
  119.         tree[i].extraBacklink = 0;  
  120.     }  
  121.     memset(ans, 0, sizeof(ans));  
  122. }  
  123.   
  124. /* 
  125.   TLE 
  126. void getAns(int suf, int pos) 
  127. { 
  128.     int letter = s[pos] - 'a'; 
  129.     while (true) 
  130.     { 
  131.         int lenPal = tree[suf].len; 
  132.         int start = tree[suf].pos-lenPal+1; 
  133.         int endd = tree[suf].pos; 
  134.         int cnt = query(1, 0, len-1, start, endd, letter); 
  135.         ans[letter][cnt] += 1; 
  136.         //printf("pos=%d | letter=%d | start=%d, endd=%d | cnt=%d | ans[%d][%d]=%d\n", pos, letter, start, endd, cnt, letter, cnt, ans[letter][cnt] ); 
  137.         suf = tree[suf].sufflink; 
  138.         if (suf <= 2) break; 
  139.     } 
  140. } 
  141. */  
  142.   
  143. int subtree[maxn];  
  144.   
  145. inline void dfs(int suf, int letter)  
  146. {  
  147.     subtree[suf] = 1;  
  148.     for (int nextNode : tree[suf].backlink)  
  149.     {  
  150.         dfs(nextNode, letter);  
  151.         subtree[suf] += subtree[nextNode] + tree[nextNode].extraBacklink;  
  152.     }  
  153.     int lenPal = tree[suf].len;  
  154.     int numBacklink = subtree[suf] + tree[suf].extraBacklink;  
  155.     int start = tree[suf].pos - lenPal + 1;  
  156.     int endd = tree[suf].pos;  
  157.     int cnt = query(1, 0, len-1, start, endd, letter);  
  158.     ans[letter][cnt] += numBacklink;  
  159. }  
  160.   
  161. int main()  
  162. {  
  163.     //freopen("in.txt", "r", stdin);  
  164.   
  165.     int tc;  
  166.     scanf("%d", &tc);  
  167.     for (int tcase = 1; tcase <= tc; tcase++)  
  168.     {  
  169.         scanf("%d", &len);  
  170.         scanf("%s", s);  
  171.         build(1, 0, len-1);  
  172.         initTree();  
  173.         for (int i = 0; i < len; i++) addLetter(i);  
  174.         for (int i = 0; i < 26; i++) dfs(tree[1].next[i], i);  
  175.         int q;  
  176.         scanf("%d", &q);  
  177.         scanf("%s", qs);  
  178.         printf("Case %d:\n", tcase);  
  179.         for (int i = 0; i < q; i++)  
  180.         {  
  181.             int cnt;  
  182.             scanf("%d", &cnt);  
  183.             int letter = qs[i] - 'a';  
  184.             if (cnt > len) puts("0");  
  185.             else printf("%d\n", ans[letter][cnt]);  
  186.         }  
  187.     }  
  188. }  

No comments:

Post a Comment

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