当前位置: 代码迷 >> 综合 >> AC自动机 hdu2222 Keywords Search
  详细解决方案

AC自动机 hdu2222 Keywords Search

热度:70   发布时间:2023-12-14 03:41:53.0

传送门:点击打开链接

题意:给一个字典,再给一个查询串,问字典中的单词一共在这个查询串中出现了多少次。

思路:裸AC自动机。。第一次做,照着bin神代码写了个模板留着以后贴

#include<map>
#include<set>
#include<cmath>
#include<ctime>
#include<stack>
#include<queue>
#include<cstdio>
#include<cctype>
#include<string>
#include<vector>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<functional>
#define fuck printf("fuck")
#define FIN freopen("input.txt","r",stdin)
#define FOUT freopen("output.txt","w+",stdout)
using namespace std;
typedef long long LL;/*MX为总长度*/
const int MX = 500000 + 5;struct AC_machine {int rear, root;int Next[MX][26], Fail[MX], End[MX];void Init() {rear = 0;root = New();}int New() {rear++;End[rear] = 0;for(int i = 0; i < 26; i++) {Next[rear][i] = -1;}return rear;}void Add(char*A) {int n = strlen(A), now = root;for(int i = 0; i < n; i++) {int id = A[i] - 'a';if(Next[now][id] == -1) {Next[now][id] = New();}now = Next[now][id];}End[now]++;}void Build() {queue<int>Q;Fail[root] = root;for(int i = 0; i < 26; i++) {if(Next[root][i] == -1) {Next[root][i] = root;} else {Fail[Next[root][i]] = root;Q.push(Next[root][i]);}}while(!Q.empty()) {int u = Q.front();Q.pop();for(int i = 0; i < 26; i++) {if(Next[u][i] == -1) {Next[u][i] = Next[Fail[u]][i];} else {Fail[Next[u][i]] = Next[Fail[u]][i];Q.push(Next[u][i]);}}}}int Query(char *S) {int n = strlen(S), now = rear, ret = 0;for(int i = 0; i < n; i++) {now = Next[now][S[i] - 'a'];int temp = now;while(temp != root) {ret += End[temp];End[temp] = 0;temp = Fail[temp];}}return ret;}
} AC;char A[100], B[MX * 2];int main() {int T, n; //FIN;scanf("%d", &T);while(T--) {scanf("%d", &n);AC.Init();for(int i = 1; i <= n; i++) {scanf("%s", A);AC.Add(A);}AC.Build();scanf("%s", B);printf("%d\n", AC.Query(B));}return 0;
}


  相关解决方案