AC自动机模板
2014-01-10 22:00
295 查看
大白书上的模板
HDU2222模板题目
/***************************
* 智商啊-。- 终于看懂AC自动机了T_T
* Date:2014/01/10
* author:crazy_石头
* algorithm:Aho-Corasick 自动机
* AC自动机=KMP+Trie
* AC自动机主要就3个部分:
* 1 建树:和普通字典树一样
* 2 建失败指针:
* ///根结点的失败指针指向自己
* ///每个结点的失败指针是从父节点的失败指针指向的结点的子结点中寻找与这个结点相同的结点
* ///如果找不到,就向上回溯直到根节点
* 同时 顺手把不存在的边都给补上,顺手建last数组
* 3 模式匹配:因为失配函数的时候顺手把不存在的边都给补上了,直接顺着失配边走下去就好了
*************************************/
HDU2222模板题目
/***************************
* 智商啊-。- 终于看懂AC自动机了T_T
* Date:2014/01/10
* author:crazy_石头
* algorithm:Aho-Corasick 自动机
* AC自动机=KMP+Trie
* AC自动机主要就3个部分:
* 1 建树:和普通字典树一样
* 2 建失败指针:
* ///根结点的失败指针指向自己
* ///每个结点的失败指针是从父节点的失败指针指向的结点的子结点中寻找与这个结点相同的结点
* ///如果找不到,就向上回溯直到根节点
* 同时 顺手把不存在的边都给补上,顺手建last数组
* 3 模式匹配:因为失配函数的时候顺手把不存在的边都给补上了,直接顺着失配边走下去就好了
*************************************/
#include <iostream> #include <cstdio> #include <cstring> #include <queue> using namespace std; const int maxn=550000; struct AC_auto { int chd[maxn][26],v[maxn],f[maxn],last[maxn],sz,ans; void init() { sz=1;ans=0; memset(v,0,sizeof(v)); memset(f,0,sizeof(f)); memset(chd[0],0,sizeof(chd[0])); } void insert(char* p) { int cur=0; for(;*p;p++) { if(!chd[cur][*p-'a']) { memset(chd[sz],0,sizeof(chd[sz])); chd[cur][*p-'a']=sz++; } cur=chd[cur][*p-'a']; } v[cur]++; } bool query(char* p) { int cur=0; for(;*p;p++) { if(!chd[cur][*p-'a']) break; cur=chd[cur][*p-'a']; } return v[cur]&&(!(*p)); } int getFail() { queue<int> q; f[0]=0; for(int c=0;c<26;c++) { int u=chd[0][c]; if(u) { f[u]=0; q.push(u); last[u]=0; } } while(!q.empty()) { int r=q.front(); q.pop(); for(int c=0;c<26;c++) { int u=chd[r][c]; if(!u){ chd[r][c]=chd[f[r]][c];continue;}///.... q.push(u); int vv=f[r]; while(vv&&!chd[vv][c]) vv=f[vv]; f[u]=chd[vv][c]; last[u]=v[f[u]] ? f[u] : last[f[u]]; } } } void solve(int j) { if(!j) return; if(v[j]) { ans+=v[j]; v[j]=0; } solve(last[j]); } void find(char* T) { int n=strlen(T),j=0; getFail(); for(int i=0;i<n;i++) { //while(j&&!chd[j][*T-'a']) j=f[j]; j=chd[j][T[i]-'a']; if(v[j]) solve(j); else if(last[j]) solve(last[j]); } } }ac; int main() { int t,n; char dic[100],str[1100000]; scanf("%d",&t); while(t--) { ac.init(); scanf("%d",&n); while(n--) { scanf("%s",dic); ac.insert(dic); } scanf("%s",str); ac.find(str); printf("%d\n",ac.ans); } return 0; }
相关文章推荐
- AC自动机 多模式串匹配 模板
- AC自动机入门+模板 (HDU 2222)
- [模板练习]AC自动机
- luogu P3796【模板】AC自动机(加强版)
- luogu P3808 【模板】AC自动机(简单版)
- 模板 AC自动机
- [模板] - AC自动机 - 静态 - 感谢小太阳
- HDU_2222 Keywords Search 【AC自动机模板题】【动态链表】
- AC自动机模板——HDU2222 Keywords Search
- hdu -2222 Keywords Search(AC自动机模板)
- ac自动机模板 1
- AC自动机 模板 【HDU2222】 Keywords Search
- HDU 3065 AC自动机模板题
- HDU 2222 - Keywords Search(AC自动机模板)
- AC自动机 模板
- AC自动机模板(数组实现版)
- 模板 AC自动机
- 【AC自动机模板】(转自木子日匀大神)
- 裸模板:AC自动机
- 【模板】AC自动机