{模板}AC自动机
来源:互联网 发布:京东数据罗盘供应商 编辑:程序博客网 时间:2024/05/21 10:01
先贴一个大白书的代码
来自这篇blog
//HDU2222#include <queue> #include <cstdio> #include <cstring>#include <iostream> #include <algorithm>using namespace std; const int N=500500; struct ACautomachine{ int chd[N][26];//孩子节点编号 int cnt[N];//当前结点 表示字符串个数 int fail[N];//失配指针 int last[N],sz,ans;//题目需要 void init() { sz=1,ans=0; memset(cnt,0,sizeof(cnt)); memset(fail,0,sizeof(fail)); memset(chd[0],0,sizeof(chd[0])); } void insert(char* p)//构建trie { 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']; } cnt[cur]++; } bool query(char* p)//题目需要 { int cur=0; for(;*p;p++) { if(!chd[cur][*p-'a']) break; cur=chd[cur][*p-'a']; } return cnt[cur]&&(!(*p)); } int getFail() { queue<int> q; fail[0]=0; for(int c=0;c<26;c++) { int u=chd[0][c]; if(u) { fail[u]=0/*Null*/; 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) { //直接指向 fail //也就是 把 trie树 的 chd[fail[r]][c]及其子孙 全部 “复制” 作r点的子孙 chd[r][c]=chd[fail[r]][c]; continue; } q.push(u); int v=fail[r]; while(v&&!chd[v][c]) v=fail[v]; //1. 令指针为 fail[fa[u]] //2. 若指针的一级儿子中存在一点(代表字符)与 u 相同 // 则令fail[u] 指向 当前指针的该儿子 //3. 否则 指针指向 fail[指针] 并重复 2 操作、 //目的:使得当前点及其到根的路径(即一个字典串) 与 fail 和fail[fail]... 所代表字典串 后缀相同 // 从而实现重新匹配 fail[u]=chd[v][c]; last[u]=cnt[fail[u]] ? fail[u] : last[fail[u]]; } } } void solve(int j) //题目需要 { if(!j) return; if(cnt[j]) { ans+=cnt[j]; cnt[j]=0; } solve(last[j]); } void find(char* T) //题目需要 { int n=strlen(T),j=0; getFail(); for(int i=0;i<n;i++) { j=chd[j][T[i]-'a']; if(cnt[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; }
自己的
刚开始一点也不注意常数
TLE了好久啊[淚]
#include <ctime>#include <cmath>#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#define fo(i,x,y) for (int i=(x);i<=(y);++i)#define fd(i,x,y) for (int i=(x);i>=(y);--i)#define oo 2139062143using namespace std;typedef long long ll;typedef double db;const int N=501000,C=27;int T,n;int ans;char dic[55],str[1100000];struct AcAutoMation{ int d[N]; int chd[N][C]; int ot[N]; int fail[N],next[N],last[N]; int bz[N]; int sz; void del(int x) { next[last[x]]=next[x],last[next[x]]=last[x]; bz[x]=1; } void init() { memset(bz,0,sizeof bz); memset(chd[0],0,sizeof chd[0]); memset(ot,0,sizeof ot); memset(fail,0,sizeof fail); sz=0; } void insert(char *p) { int tmp=0; int len=strlen(p+1); fo(i,1,len) { int now=p[i]-'a'; if(!chd[tmp][now]) { chd[tmp][now]=++sz; memset(chd[sz],0,sizeof(chd[sz])); } tmp=chd[tmp][now]; } ++ot[tmp]; } void Getfail() { int tmp=0; int hd=0,tl=0; fo(i,0,25) { if(chd[0][i]) { d[++tl]=chd[0][i]; fail[chd[0][i]]=0; } } while(hd++<tl) { tmp=d[hd]; fo(i,0,25) if(chd[tmp][i]) { d[++tl]=chd[tmp][i]; int to=fail[tmp]; while(to!=0&&!chd[to][i]) to=fail[to]; fail[chd[tmp][i]]=chd[to][i]; next[chd[tmp][i]]=(ot[chd[tmp][i]])?(fail[chd[tmp][i]]):(next[fail[chd[tmp][i]]]); } } } void solve(char *p) { int tmp=0; int len=strlen(p+1); fo(i,1,len) { int now=p[i]-'a',to=tmp; while(!chd[to][now]&&to) to=fail[to]; tmp=chd[to][now]; for (int pp=tmp;pp;pp=next[pp]) { if(ot[pp]) { ans+=ot[pp],ot[pp]=0; } } } }}ac;int main(){ int TT=clock(); scanf("%d\n",&T); while(T--) { ac.init(); scanf("%d\n",&n); fo(i,1,n) { scanf("%s\n",dic+1); ac.insert(dic); } ac.Getfail(); ans=0; scanf("%s\n",str+1); ac.solve(str); printf("%d\n",ans); } return 0;}
阅读全文
1 0
- 【AC自动机】AC自动机模板
- AC自动机模板
- AC自动机模板
- AC自动机模板
- AC自动机模板
- AC自动机模板
- AC自动机模板
- AC自动机模板 hdu2222
- AC自动机模板
- AC自动机模板
- 数据结构--AC自动机--模板
- ac自动机模板
- AC自动机模板
- AC自动机模板
- hdu2222 ac自动机模板
- ac自动机模板。。。。。
- AC自动机模板 LA4670
- AC自动机模板
- 记录一个显示C++编程环境的HTML代码
- php html_entity_decode使用总结
- 关于R在Linux服务器上生成图片中文乱码原因及解决办法
- Axure+RP+pro教程(2)
- 数据库的隔离级别与innodb引擎MVCC机制
- {模板}AC自动机
- DevOps for Web Development.pdf 英文原版 免费下载
- Android简单实现一个颜色渐变的ProgressBar
- [spm操作] 什么是ROI,如何做ROI以及批量提取ROI的%signal change的示例程序
- FastDFS浅析和架构图
- CentOS 7 最小安装不能发现eth0
- Html与Js连用实现动画
- 使用java解压GZip文件
- jQuery form插件的使用--ajaxForm()和ajaxSubmit()的可选参数项对象