Advertisement
Saleh127

Light OJ 1427 / Aho-Corasick

Feb 21st, 2023
717
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.42 KB | None | 0 0
  1. /***
  2.  created: 2023-02-21-21.07.56
  3. ***/
  4.  
  5. #include <bits/stdc++.h>
  6. #include <ext/pb_ds/assoc_container.hpp>
  7. #include <ext/pb_ds/tree_policy.hpp>
  8. using namespace std;
  9. using namespace __gnu_pbds;
  10. template<typename U> using ordered_set=tree<U, null_type,less<U>,rb_tree_tag,tree_order_statistics_node_update>;
  11. #define ll int
  12. #define all(we) we.begin(),we.end()
  13. #define test int tt; cin>>tt; for(int cs=1;cs<=tt;cs++)
  14. #define nl '\n'
  15.  
  16. /* Template Aho-Corasick by Anachor */
  17.  
  18. namespace Aho{
  19.    
  20. const int N = 5e5 + 7;        ///Number of characters in dictionary
  21. const int K = 26;           ///Alphabet size
  22.  
  23. int nxt[N][K];              ///Children
  24. int go[N][K];               ///automaton
  25.  
  26. int link[N];                ///Suffix link
  27. bool leaf[N];               ///isLeaf
  28. int par[N];                 ///Parent
  29. char ch[N];                 ///character of incoming edge
  30. int ex[N];                  ///exit link
  31. int sz;
  32. vector<int> finish[N];      ///finish string index
  33.  
  34. void init()
  35. {
  36.     memset(nxt, -1, sizeof nxt);
  37.     memset(go, -1, sizeof go);
  38.     memset(link, -1, sizeof link);
  39.     memset(leaf, 0, sizeof leaf);
  40.     memset(ex, -1, sizeof ex);
  41.     for (int i = 0; i < N; i++)
  42.     {
  43.         finish[i].clear( );
  44.     }
  45.     sz = 0;
  46. }
  47.  
  48. void addString(const string &s, int ind)
  49. {
  50.     int cur = 0;
  51.     for (char c: s)
  52.     {
  53.         int cc = c-'a';
  54.         if (nxt[cur][cc] == -1)
  55.         {
  56.             nxt[cur][cc] = ++sz;
  57.             ch[sz] = c;
  58.             par[sz] = cur;
  59.         }
  60.         cur = nxt[cur][cc];
  61.     }
  62.     leaf[cur] = 1;
  63.     finish[cur].emplace_back(ind);
  64. }
  65.  
  66. int Go(int v, char ch);
  67.  
  68. ///Amortized O(1)
  69. int getlink(int v)
  70. {
  71.     if (link[v] != -1)  return link[v];
  72.     if (v==0 || par[v] == 0)    return link[v] = 0;
  73.     else return link[v] = Go(getlink(par[v]), ch[v]);
  74. }
  75.  
  76. ///Amortized O(1)
  77. int Go (int v, char c)
  78. {
  79.     int cc = c- 'a';
  80.     if (go[v][cc] != -1)     return go[v][cc];
  81.     if (nxt[v][cc] != -1)    return go[v][cc] = nxt[v][cc];
  82.     else return go[v][cc] = (v ? Go(getlink(v), c) : 0);
  83. }
  84.  
  85. ///Amortized O(1)
  86. int exitlink(int v)
  87. {
  88.     if (ex[v] != -1)             return ex[v];
  89.     int nxt = getlink(v);
  90.     if (nxt==0 || leaf[nxt])     return ex[v] = nxt;
  91.     return ex[v] = exitlink(nxt);
  92. }
  93.  
  94.  
  95. ///returns number of matches (including multiple matches)
  96. ///O(no of matches + length of s)
  97. int match(string s)
  98. {
  99.     int cur = 0;
  100.     int ans = 0;
  101.     for (auto c: s)
  102.     {
  103.         cur = Go(cur, c);
  104.         int e = (leaf[cur] ? cur : exitlink(cur));
  105.         while (e)
  106.             ans++,
  107.                 e = exitlink(e);
  108.     }
  109.     return ans;
  110. }
  111. }
  112.  
  113.  
  114. int main()
  115. {
  116.     ios_base::sync_with_stdio(0);
  117.     cin.tie(0);
  118.     cout.tie(0);
  119.  
  120.     test
  121.     {
  122.         Aho::init();
  123.  
  124.         ll n;
  125.  
  126.         string a,b;
  127.  
  128.         cin>>n;
  129.  
  130.         cin>>a;
  131.  
  132.         vector<ll>ans(n,0);
  133.  
  134.         for(ll i=0; i<n; i++)
  135.         {
  136.             cin>>b;
  137.             Aho::addString(b,i);
  138.         }
  139.  
  140.         ll cur=0;
  141.  
  142.         for(ll i=0; a[i]; i++)
  143.         {
  144.             cur=Aho::Go(cur,a[i]);
  145.  
  146.             ll en;
  147.            
  148.             if(Aho::leaf[cur]) en=cur;
  149.             else en=Aho::exitlink(cur);
  150.  
  151.             while(en>0)
  152.             {
  153.                 for (ll j:Aho::finish[en]) ans[j]++;
  154.  
  155.                 en=Aho::exitlink(en);
  156.             }
  157.         }
  158.  
  159.         cout<<"Case "<<cs<<":"<<nl;
  160.  
  161.         for(ll i:ans) cout<<i<<nl;
  162.     }
  163.     return 0;
  164. }
  165.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement