AC自动机
来源:互联网 发布:屏幕碎裂的软件 编辑:程序博客网 时间:2024/04/29 13:29
md,弄这个原理就弄了好久。。
还是得多写写,不然又忘了。
这是模板题<–点它
#include<iostream>#include<cstdio>#include<cstring>#define mk(a) memset(a,0,sizeof(a))using namespace std;const int N=1001000;struct ACMachine{ int s[N][26],fail[N],w[N];//s是trie数组,fail是指针数组,w是字符的个数 char S[N<<1]; bool ex[N];//ex表示是否是单词的节点 int dl[N];//以bfs的序列进行遍历 int n,tot,ans; int newnode() { fail[++tot]=0; ex[tot]=0; for(int i=0;i<26;i++)s[tot][i]=0; return tot; } void insert(char *a) { int len=strlen(a),u=1; for(int i=0,j=a[i]-'a';i<len;j=a[++i]-'a') u=s[u][j]?s[u][j]:s[u][j]=newnode(); w[u]++; ex[u]=1; } void got(int p) { for(int i=0;i<26;i++) { int tmp=s[fail[p]][i]; if(s[p][i])fail[s[p][i]]=tmp,ex[s[p][i]]|=ex[tmp]; else s[p][i]=tmp; } } void getfail()//bfs序 { int u=0,d=0,p; for(dl[++u]=1;u>d;got(p)) { p=dl[++d]; for(int i=0;i<26;i++) if(s[p][i])dl[++u]=s[p][i]; } } void init() { tot=1; mk(w); mk(ex); mk(fail); mk(s); fail[1]=0; for(int i=0;i<26;i++)s[0][i]=1; } void read() { char a[20]; scanf("%d",&n); getchar(); for(int i=1;i<=n;i++) gets(a),insert(a); gets(S); } void runarun() { int len=strlen(S),u=1; for(int i=0,j=S[i]-'a';i<len;j=S[++i]-'a') { if(j>=0 && j<26)u=s[u][j]; else {u=1;continue;}// cout<<u<<" "<<w[u]<<" "<<ex[u]<<endl; for(int p=u; p>1 && ex[p];p=fail[p])ans+=w[p],w[p]=0; } } void work() { init(); read(); getfail();//失败指针 ans=0; runarun(); printf("%d\n",ans); }}d;int main(){ int T; scanf("%d",&T); while(T--)d.work(); return 0;}
0 1
- AC自动机...
- AC自动机
- AC 自动机
- AC自动机
- AC自动机
- ac自动机
- ac自动机
- AC自动机
- AC自动机
- AC自动机
- AC自动机
- AC自动机
- AC 自动机
- ac自动机
- AC自动机
- AC自动机
- AC自动机
- AC自动机
- Evaluate Reverse Polish Notation
- rabbitmq3.4.2 shell脚本分析
- 1009. 说反话 (20)
- dns
- 打开发动
- AC自动机
- BZOJ 1059: [ZJOI2007]矩阵游戏
- IntelliJ Idea 常用快捷键
- 积分图
- systemd命令
- 189. Rotate Array
- log4j.properties配置详解
- dedecms 循环当前栏目下的二级栏目
- MULTITHREADING - PRODUCER AND CONSUMER WITH QUEUE