Saturday, June 1, 2019

[Codeforces] D. Frequency of String

Author            : Dipu Kumar Mohanto 
                    CSE, Batch - 6
                    BRUR.
Problem Statement : D. Frequency of String
Source            : Codeforces
Category          : Data Structure, String
Algorithm         : Aho Corasick Algorithm
Verdict           : Accepted

  1. #include <bits/stdc++.h>  
  2.   
  3. using namespace std;  
  4.   
  5. #define memo(a, b)                      memset(a, b, sizeof a)  
  6.   
  7. static const int maxn = 5e5 + 5;  
  8.   
  9. int Next[27][maxn], End[maxn], sz, Num[maxn], backPoint[maxn];  
  10. bool created[maxn];  
  11. vector <int> out[maxn], patternIndices[maxn], occur[maxn];  
  12.   
  13. string text, pattern[maxn];  
  14. int numPat, k[maxn];  
  15.   
  16.   
  17. void init()  
  18. {  
  19.       sz = 0;  
  20.       memo(Next, 0);  
  21.       memo(created, 0);  
  22.       memo(Num, 0);  
  23.       for (int i = 0; i < maxn; i++)  
  24.       {  
  25.             out[i].clear();  
  26.             patternIndices[i].clear();  
  27.       }  
  28. }  
  29.   
  30. void insertPattern(const string &pat, const int id)  
  31. {  
  32.       int v = 0;  
  33.       for (char ch : pat)  
  34.       {  
  35.             int val = ch - 'a';  
  36.             if (!created[ Next[val][v] ])  
  37.             {  
  38.                   ++sz;  
  39.                   Next[val][v] = sz;  
  40.                   created[sz] = 1;  
  41.             }  
  42.             v = Next[val][v];  
  43.       }  
  44.       patternIndices[v].emplace_back(id);  
  45. }  
  46.   
  47. void findBackPointer() // Build Failure Function  
  48. {  
  49.       queue <int> PQ;  
  50.       int v = 0;  
  51.       for (int i = 0; i < 26; i++)  
  52.       {  
  53.             if (Next[i][v])  
  54.             {  
  55.                   PQ.emplace(Next[i][v]);  
  56.                   backPoint[ Next[i][v] ] = v;  
  57.                   out[v].emplace_back(Next[i][v]);  
  58.             }  
  59.       }  
  60.       while (!PQ.empty())  
  61.       {  
  62.             int u = PQ.front(); PQ.pop();  
  63.             for (int i = 0; i < 26; i++)  
  64.             {  
  65.                   int v = Next[i][u];  
  66.                   if (!v) continue;  
  67.                   int w = backPoint[u];  
  68.                   while (w && Next[i][w] == 0) w = backPoint[w];  
  69.                   backPoint[v] = Next[i][w];  
  70.                   out[ Next[i][w] ].push_back(v);  
  71.                   for (int p : patternIndices[ Next[i][w] ]) patternIndices[v].push_back(p);  
  72.                   PQ.emplace(v);  
  73.             }  
  74.       }  
  75. }  
  76.   
  77. void insertText(const string &text)  
  78. {  
  79.       int v = 0;  
  80.       for (int i = 0; i < text.size(); i++)  
  81.       {  
  82.             int val = text[i] - 'a';  
  83.             while (v && Next[val][v] == 0) v = backPoint[v];  
  84.             v = Next[val][v];  
  85.             for (int p : patternIndices[v]) occur[p].push_back(i);  
  86.       }  
  87. }  
  88.   
  89. int query(int id)  
  90. {  
  91.       int len = pattern[id].size();  
  92.       int occ = occur[id].size();  
  93.       if (occ < k[id]) return -1;  
  94.       int mini = 1e7;  
  95.       for (int i = 0, j = k[id] - 1; j < occ; i++, j++) mini = min(mini, occur[id][j] - occur[id][i]);  
  96.       return mini + len;  
  97. }  
  98.   
  99. signed main()  
  100. {  
  101.       ios_base::sync_with_stdio(false);  
  102.       cin.tie(nullptr);  
  103.       cout.tie(nullptr);  
  104.       cout << fixed << setprecision(3);  
  105.   
  106.       #ifndef ONLINE_JUDGE  
  107.             freopen("in.txt""r", stdin);  
  108.       #endif // ONLINE_JUDGE  
  109.   
  110.       init();  
  111.   
  112.       cin >> text >> numPat;  
  113.       for (int i = 1; i <= numPat; i++)  
  114.       {  
  115.             cin >> k[i] >> pattern[i];  
  116.             insertPattern(pattern[i], i);  
  117.       }  
  118.       findBackPointer();  
  119.       insertText(text);  
  120.       for (int i = 1; i <= numPat; i++) cout << query(i) << '\n';  
  121. }  


No comments:

Post a Comment

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