hdu5384(AC自动机)
2015-08-17 16:04
351 查看
哇,ac自动机好快呀!看的是匡斌的模板,自己有些了一遍,这个链接该怎么贴呢?这样可以吗?
kuangbin的模板:http://download.csdn.net/detail/howe_young/8112607,感觉kuagnbin写的模板很干净。
一开始写这道题时,想着ac自动机占的空间太大了,写不了,比赛完了后,现在才发现,开一个差不多大的数组就可以了,不用那么较真
(今天中午和队友一起吃的是蛋汁牛肉饭,因为其他的牛肉饭都有胡萝卜,虽然米饭中有很多牛肉汤在泡着米饭,但是米饭有点硬,如果米饭再香一点,软一点,汤再少一点应该会更好吃吧!队友说泡菜味的面挺好吃的。)
2015.8.29:
又把ac自动机的过程想了一下,理顺了一下,大概就是模板,根据题中不同的意思,再做相应的改变。
(面包陪那个泡菜味的面挺好吃的,小的时候喜欢吃米饭,因为在北方,米饭不常吃,但是自从住校以后,就喜欢吃饼了,喜欢吃饼沾麻酱,我们那有一句话,叫大葱蘸酱,越吃越胖,不知道是哪种酱,还是指所有的!
)
kuangbin的模板:http://download.csdn.net/detail/howe_young/8112607,感觉kuagnbin写的模板很干净。
一开始写这道题时,想着ac自动机占的空间太大了,写不了,比赛完了后,现在才发现,开一个差不多大的数组就可以了,不用那么较真
(今天中午和队友一起吃的是蛋汁牛肉饭,因为其他的牛肉饭都有胡萝卜,虽然米饭中有很多牛肉汤在泡着米饭,但是米饭有点硬,如果米饭再香一点,软一点,汤再少一点应该会更好吃吧!队友说泡菜味的面挺好吃的。)
2015.8.29:
又把ac自动机的过程想了一下,理顺了一下,大概就是模板,根据题中不同的意思,再做相应的改变。
(面包陪那个泡菜味的面挺好吃的,小的时候喜欢吃米饭,因为在北方,米饭不常吃,但是自从住校以后,就喜欢吃饼了,喜欢吃饼沾麻酱,我们那有一句话,叫大葱蘸酱,越吃越胖,不知道是哪种酱,还是指所有的!
)
#include<stdio.h> #include<string.h> #include<iostream> #include<queue> using namespace std; #define N 100010 #define M 26 #define X 10010 char sentencea [X]; char worda[X]; struct AC{ int nexta [M]; int faila ; int enda ; int L; int root; int newnode(){ for(int i=0;i<M;i++){ nexta[L][i]=-1; } enda[L++]=0; return L-1; } void init(){ L=0; root=newnode(); } void assert(char word[]){ int now=root; for(int i=0;word[i]!='\0';i++){ int tempch=word[i]-'a'; if(nexta[now][tempch]==-1){ nexta[now][tempch]=newnode(); } now=nexta[now][tempch]; } enda[now]++; } void build(){ queue<int> q; for(int i=0;i<M;i++){ if(nexta[root][i]==-1){ nexta[root][i]=root;//nexta[root][i]都不存在了,哪还有什么root一直到nexta[root][i]都相等这一说,所以当然不存在fail[nexta[root][i]]?乖,回去重新比较! } else{ faila[nexta[root][i]]=root;//这里nexta[root][i]已经非-1了,不需要重新赋值,但是由于nexta[root][i]是存在的所以存在一种可能从root一直到nexta[root][i]一直相等,所以好吧,给你个fail[nexta[root][i]] q.push(nexta[root][i]); } } while(!q.empty()){ int temp=q.front(); q.pop(); for(int i=0;i<M;i++){ if(nexta[temp][i]==-1){ nexta[temp][i]=nexta[faila[temp]][i]; } else{ faila[nexta[temp][i]]=nexta[faila[temp]][i]; q.push(nexta[temp][i]); } } } } long long int query(char sentence[]){ int now=root; long long int ans=0; for(int i=0;sentence[i]!='\0';i++){//printf("wo shi da hao ren"); now=nexta[now][sentence[i]-'a']; int temp=now; while(temp!=root){ ans+=(long long int)enda[temp]; temp=faila[temp]; } } return ans; } }; AC ac;//为什么这个必须定义到外面? int main(){ int t; int n,m; scanf("%d",&t); while(t--){ scanf("%d%d",&n,&m); //AC ac; ac.init(); for(int i=0;i<n;i++){ scanf("%s",sentencea[i]); } for(int i=0;i<m;i++){ scanf("%s",worda); ac.assert(worda); } ac.build(); for(int i=0;i<n;i++){ printf("%lld\n",ac.query(sentencea[i])); } } return 0; }
相关文章推荐
- [HDOJ4349]Xiao Ming's Hope
- Choose the best route 2680 (dijkstra,反向建图)
- 进程 服务器编程入门
- POJO
- 用Go写了一个小工具,用他脚本下载日志文件,然后让开发自己去下载
- HDU 5087 Revenge of LIS II(次大递增子序列)
- LeetCode(34)Search for a Range
- PCB过孔全介绍
- MySQL Workbench正向逆向工程
- linux网络设备驱动学习
- wxString类型转化
- mysql分组取每组前几条记录
- LeetCode(34)Search for a Range
- 关于Oracle在where子句中引用列别名问题的分析
- LINGO出错时错误代码含义:
- 线段树专题—ZOJ1610 Count the Colors
- Java基本数据类型总结
- 1094. The Largest Generation (25)
- 安卓 SurfaceView 画图
- Getting started with Javacc