hdu2222,AC自动机,trie图
2016-05-28 00:59
141 查看
这题神坑啊。。主要有2个坑点
1.重复的不算,比如输入:
1
1
he
hehe 一开始以为输出为2,,结果经过大量wa证明,输出是1
2输入中重复的词可以叠加,比如输入:
1
2
he
he
he 输出是2而不是1,,,,导致我wa了,,几十次。。
//2016年11月1日更新
嫌当初的代码风格太丑了,整理模板的时候,时隔半年又来重写了一下这道题
却发现这道题的数据不够严
比如
1
4
sher
he
say
her
sherhs
输出2,3都AC了,
正解应该是输出3把;
下面上AC自动机的代码(已更新):
1.重复的不算,比如输入:
1
1
he
hehe 一开始以为输出为2,,结果经过大量wa证明,输出是1
2输入中重复的词可以叠加,比如输入:
1
2
he
he
he 输出是2而不是1,,,,导致我wa了,,几十次。。
//2016年11月1日更新
嫌当初的代码风格太丑了,整理模板的时候,时隔半年又来重写了一下这道题
却发现这道题的数据不够严
比如
1
4
sher
he
say
her
sherhs
输出2,3都AC了,
正解应该是输出3把;
下面上AC自动机的代码(已更新):
#include<iostream> #include<cstdio> #include<math.h> #include<algorithm> #include<queue> #include<string.h> #include<cstring> using namespace std; #define FIN freopen("input.txt","r",stdin) #define N 1111111 int n; char s[1000000+10]; struct AC_trie { int root,cnt; int End[500000+10],to[500000+10][27],fail[500000+10];//改 int newnode() { for(int i=0; i<26; i++) to[cnt][i]=-1; End[cnt]=0; return cnt++; } void init() { cnt=0; root=newnode(); } void insert(char *s) { int now=root; for(char *ss=s; *ss; ss++) { int v=*ss-'a';//改 if(to[now][v]==-1)to[now][v]=newnode(); now=to[now][v]; } End[now]++;//改 } void build() { queue<int> my; fail[root]=root; for(int i = 0; i < 26; i++) if(to[root][i] == -1) to[root][i]= root; else { fail[to[root][i]]=root; my.push(to[root][i]); } while(!my.empty()) { int u=my.front(); my.pop(); for(int i=0; i<26; i++) //改 { int v=to[u][i]; if(v!=-1) { fail[v]=to[fail[u]][i]; my.push(v); } else to[u][i]=to[fail[u]][i]; } } } int query(char *s) { int ans=0; int now=root; for(char *ss=s; *ss; ss++) { int v=*ss-'a'; now=to[now][v]; int cur=now; while(cur!=root&&End[cur])//错误数据主要在这里,while(cur!=root)时输出为3,while(cur!=root&&End[cur])时输出为2,两者运行时间差4倍 { ans+=End[cur]; End[cur]=0; cur=fail[cur]; } } return ans; } } AC; int main() { FIN; int _; scanf("%d",&_); while(_--) { scanf("%d",&n); AC.init(); for(int i=1; i<=n; i++) { scanf("%s",s); AC.insert(s); } AC.build(); scanf("%s",s); printf("%d\n",AC.query(s)); } return 0; }
相关文章推荐
- VC中TRACE()的用法
- 简读RSS-MVVM模式的安卓客户端实现
- Java基础回顾 : 文件类中的一些常用的方法
- 第一次写博客
- 5种页面置换算法的实现
- web轮播图 可配置循环左右滚动
- iOS 正则表达式(二) RegexKitLite使用
- java学习总结(16.05.28~16.05.29)使用svn管理源代码
- ffmpeg 编译
- 一切从现在开始
- LeetCode-241.Different Ways to Add Parentheses
- [Android]Android图片压缩(质量压缩和尺寸压缩)
- fragment中使用setOnItemClickListener监听无效的解决办法
- struts2第一天基础配置 action package result 全局result redirect chain redirectAction
- 图片转字符画
- 测试测试
- Android Retrofit 2.0自定义JSONObject Converter
- 树莓派学习系列4——用Scratch创建游戏剧情
- Spring 事务机制详解
- 单例模式