bingxuan9112

AC自動機

Jan 25th, 2020
245
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 1.73 KB | None | 0 0
  1. #include <iostream>
  2. #include <cstring>
  3. #define mem(v,x) memset(v,x,sizeof v)
  4.  
  5. using namespace std;
  6. const int N = 400025, K = 26;
  7.  
  8. struct AhoCorasick {
  9.     int tot, ch[N][K], ans[N], fail[N]; // root = 0
  10.     int q[N], head, tail; // queue 儲存BFS順序以計算答案
  11.     void init() {
  12.         tot = head = tail = 0;
  13.         mem(ch, 0), mem(ans, 0), mem(fail, 0);
  14.     }
  15.     int ins(const string &s) {
  16.         int i = 0;
  17.         for(char c: s) {
  18.             if(!ch[i][c-'a']) ch[i][c-'a'] = ++tot;
  19.             i = ch[i][c-'a'];
  20.         }
  21.         return i;
  22.     }
  23.     void get_fail() {
  24.         for(int c = 0; c < K; c++) if(ch[0][c]) q[tail++] = ch[0][c];
  25.         while(head != tail) {
  26.             int i = q[head++];
  27.             for(int c = 0; c < K; c++) if(ch[i][c]) {
  28.                 int j = fail[i];
  29.                 while(j && !ch[j][c]) j = fail[j];
  30.                 if(ch[j][c]) j = ch[j][c];
  31.                 fail[ch[i][c]] = j;
  32.                 q[tail++] = ch[i][c];
  33.             }
  34.         }
  35.     }
  36.     void run(const string &s) {
  37.         int i = 0;
  38.         for(char c: s) {
  39.             while(i && !ch[i][c-'a']) i = fail[i];
  40.             if(ch[i][c-'a']) i = ch[i][c-'a'];
  41.             ++ans[i];
  42.         }
  43.         for(int i = tot-1; i >= 0; i--) {
  44.             int x = q[i];
  45.             ans[fail[x]] += ans[x];
  46.         }
  47.     }
  48. } AC;
  49. int endnode[N];
  50. void solve() {
  51.     int n;
  52.     string T, P;
  53.     cin >> T >> n;
  54.     AC.init();
  55.     for(int i = 0; i < n; i++) cin >> P, endnode[i] = AC.ins(P);
  56.     AC.get_fail();
  57.     AC.run(T);
  58.     for(int i = 0; i < n; i++) cout << AC.ans[endnode[i]] << '\n';
  59. }
  60. signed main() {
  61.     ios_base::sync_with_stdio(0), cin.tie(0);
  62.     int t;
  63.     cin >> t;
  64.     while(t--) solve();
  65. }
Advertisement
Add Comment
Please, Sign In to add comment