Sunday, June 2, 2019

[Codeforces] F. String Set Queries

Author            : Dipu Kumar Mohanto 
                    CSE, Batch - 6
                    BRUR.
Problem Statement : F. String Set Queries
Source            : Codeforces
Category          : String
Algorithm         : Aho Corasick Algorithm - Dynamic 
Verdict           : Accepted

  1. #include <bits/stdc++.h>  
  2.   
  3. using namespace std;  
  4.   
  5. static const int maxn = 3e5 + 5;  
  6. static const int logn = 20;  
  7.   
  8. struct AhoCorasick  
  9. {  
  10.       int sz, Num[maxn], backPoint[maxn];  
  11.       map <charint> Next[maxn];  
  12.   
  13.       void init()  
  14.       {  
  15.             assert(sz < maxn);  
  16.             for (int i = 0; i <= sz; i++)  
  17.             {  
  18.                   Num[i] = 0;  
  19.                   backPoint[i] = -1;  
  20.                   Next[i].clear();  
  21.             }  
  22.             sz = 0;  
  23.       }  
  24.       AhoCorasick()  
  25.       {  
  26.             init();  
  27.       }  
  28.       void insertPattern(const string &pat)  
  29.       {  
  30.             int v = 0;  
  31.             for (char ch : pat)  
  32.             {  
  33.                   if (Next[v].count(ch) == 0) Next[v][ch] = ++sz;  
  34.                   v = Next[v][ch];  
  35.             }  
  36.             Num[v]++;  
  37.       }  
  38.       void findBackPointer() // Build Failure Function  
  39.       {  
  40.             queue <int> PQ;  
  41.             PQ.emplace(0);  
  42.             int v = 0;  
  43.             while (!PQ.empty())  
  44.             {  
  45.                   int u = PQ.front(); PQ.pop();  
  46.                   for (auto it : Next[u])  
  47.                   {  
  48.                         int v = it.second;  
  49.                         char ch = it.first;  
  50.                         int w = backPoint[u];  
  51.                         while (w != -1 && Next[w].count(ch) == 0) w = backPoint[w];  
  52.                         if (w == -1) backPoint[v] = 0;  
  53.                         else backPoint[v] = Next[w][ch];  
  54.                         Num[v] += Num[ backPoint[v] ];  
  55.                         PQ.emplace(v);  
  56.                   }  
  57.             }  
  58.       }  
  59.       int insertTextAndQuery(const string &text)  
  60.       {  
  61.             int v = 0;  
  62.             int ans = 0;  
  63.             for (char ch : text)  
  64.             {  
  65.                   while (v != -1 && Next[v].count(ch) == 0) v = backPoint[v];  
  66.                   if (v == -1) v = 0;  
  67.                   else v = Next[v][ch];  
  68.                   ans += Num[v];  
  69.             }  
  70.             return ans;  
  71.       }  
  72. };  
  73.   
  74. struct AhoCorasickDynamic  
  75. {  
  76.       vector <string> lst[logn];  
  77.       AhoCorasick aho[logn];  
  78.   
  79.       void init()  
  80.       {  
  81.             for (int i = 0; i < logn; i++)  
  82.             {  
  83.                   lst[i].clear();  
  84.                   aho[i].init();  
  85.             }  
  86.       }  
  87.       AhoCorasickDynamic()  
  88.       {  
  89.             init();  
  90.       }  
  91.       void insertPattern(const string &pat)  
  92.       {  
  93.             int position = 0;  
  94.             for (int i = 0; i < logn; i++)  
  95.             {  
  96.                   if (lst[i].empty())  
  97.                   {  
  98.                         position = i;  
  99.                         break;  
  100.                   }  
  101.             }  
  102.             lst[position].emplace_back(pat);  
  103.             aho[position].insertPattern(pat);  
  104.             for (int i = 0; i < position; i++)  
  105.             {  
  106.                   aho[i].init();  
  107.                   for (string p : lst[i])  
  108.                   {  
  109.                         lst[position].emplace_back(p);  
  110.                         aho[position].insertPattern(p);  
  111.                   }  
  112.                   lst[i].clear();  
  113.             }  
  114.             aho[position].findBackPointer();  
  115.       }  
  116.       int query(const string &text)  
  117.       {  
  118.             int ans = 0;  
  119.             for (int i = 0; i < logn; i++) ans += aho[i].insertTextAndQuery(text);  
  120.             return ans;  
  121.       }  
  122. };  
  123.   
  124. AhoCorasickDynamic add;  
  125. AhoCorasickDynamic del;  
  126.   
  127. signed main()  
  128. {  
  129.       ios_base::sync_with_stdio(false);  
  130.       cin.tie(nullptr);  
  131.       cout.tie(nullptr);  
  132.       cout << fixed << setprecision(3);  
  133.   
  134.       #ifndef ONLINE_JUDGE  
  135.             freopen("in.txt""r", stdin);  
  136.       #endif // ONLINE_JUDGE  
  137.   
  138.       int n;  
  139.       cin >> n;  
  140.       int type;  
  141.       string s;  
  142.       for (int i = 0; i < n; i++)  
  143.       {  
  144.             cin >> type >> s;  
  145.             if (type == 1) add.insertPattern(s);  
  146.             else if (type == 2) del.insertPattern(s);  
  147.             else cout << (add.query(s) - del.query(s)) << endl;  
  148.       }  
  149.   
  150. }  

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. }