Keywords Search HDU - 2222(AC自动机)

题目链接

题意:给你一个长度为n的单词表,一个文本串,问你这个文本串中出现了单词表中多少个单词;

思路:老模板题了,记录一下结尾字母累加就好了。

#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + 6;
int n;

namespace AC {
int tr[N][26], tot;
int e[N], fail[N];
void insert(char *s) {
  int u = 0;
  for (int i = 1; s[i]; i++) {
    if (!tr[u][s[i] - 'a']) tr[u][s[i] - 'a'] = ++tot;
    u = tr[u][s[i] - 'a'];
  }
  e[u]++;
}
queue<int> q;
void build() {
  for (int i = 0; i < 26; i++)
    if (tr[0][i]) q.push(tr[0][i]);
  while (q.size()) {
    int u = q.front();
    q.pop();
    for (int i = 0; i < 26; i++) {
      if (tr[u][i])
        fail[tr[u][i]] = tr[fail[u]][i], q.push(tr[u][i]);
      else
        tr[u][i] = tr[fail[u]][i];
    }
  }
}
int query(char *t) {
  int u = 0, res = 0;
  for (int i = 1; t[i]; i++) {
    u = tr[u][t[i] - 'a'];  // 转移
    for (int j = u; j && e[j] != -1; j = fail[j]) {
      res += e[j], e[j] = -1;
    }
  }
  return res;
}
void init(){
    memset(tr,0,sizeof(tr));
    tot=0;
    memset(fail,0,sizeof(fail));
    memset(e,0,sizeof(e));
    
}
}  // namespace AC

char s[N];
int main() {
    int T;
    scanf("%d",&T);
    while(T--){
        AC::init();
  scanf("%d", &n);
  for (int i = 1; i <= n; i++) scanf("%s", s + 1), AC::insert(s);
  scanf("%s", s + 1);
  AC::build();
  printf("%d\n", AC::query(s));
}
  return 0;
}

 

posted @ 2020-09-23 20:42  Ldler  Views(94)  Comments(0Edit  收藏  举报