题目链接:https://cn.vjudge.net/problem/HDU-2222

题意

给一些关键词,和一个待查询的字符串

问这个字符串里包含多少种关键词

思路

AC自动机模版题咯

注意一般情况不需要修改build方法,就像kmp里的getfail一样

一般的题目就是改改insert,query

一开始写的模版总是有问题,懒得改了

直接找的kuangbin的模版【原创】AC自动机小结

注意数组和指针的效率差不了多少,此题同一个算法的指针形式(296ms)比数组(187ms)慢110ms

说实在的,数组写法就是优雅。

网上那些指针的看着就难受,明明是好好的逻辑,变量名都是pqrvtxy,搞的跟被混淆了一样。

改了两套没一个舒服的,真难受。

提交过程

AC

代码

#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
const int ACSize=500000+20;
const int maxitem=26, maxn=1e4+20, maxword=50+20, maxl=1e6+20;
char word[maxword], line[maxl];
struct Trie{
int next[ACSize][26], fail[ACSize], cnt[ACSize];
int root, total;
int newnode(void){
for(int pos=0; pos<maxitem; pos++)
next[total][pos]=-1;
cnt[total]=0;
return total++;
} void init(){
total=0;
root=newnode();
} void insert(char buf[]){
int now=root;
for(int i=0; buf[i]; i++){
int pos=buf[i]-'a';
if(next[now][pos]==-1)
next[now][pos]=newnode();
now=next[now][pos];
}
cnt[now]++;
} void build(void){
queue<int> que;
fail[root]=root;
for(int i=0; i<maxitem; i++)
if(next[root][i]==-1)
next[root][i]=root;
else{
fail[next[root][i]]=root;
que.push(next[root][i]);
} while(!que.empty()){
int now=que.front(); que.pop(); for(int pos=0; pos<maxitem; pos++)
if(next[now][pos]==-1)
next[now][pos]=next[fail[now]][pos];
else{
fail[next[now][pos]]=next[fail[now]][pos];
que.push(next[now][pos]);
}
}
} int query(char buf[]){
int now=root, res=0;
for(int i=0; buf[i]; i++){
int pos=buf[i]-'a';
now=next[now][pos];
for (int tmp=now; tmp!=root && cnt[tmp]!=-1; tmp=fail[tmp]){
res+=cnt[tmp];
cnt[tmp]=-1; // 注意此处,找到了就不要找第二次了,直接删除即可
}
}return res;
} void debug(void){
for(int i=0; i<total; i++){
printf("id=%3d, fail=%3d, end=%3d [", i, fail[i], cnt[i]);
for(int j=0; j<maxitem; j++)
printf("%2d", next[i][j]);
printf("]\n");
}
}
}AC; int main(void){
int T, n; scanf("%d", &T);
while (T--){
AC.init();
scanf("%d", &n);
for (int i=0; i<n; i++){
scanf("%s", word);
AC.insert(word);
}AC.build(); scanf("%s", line);
printf("%d\n", AC.query(line));
} return 0;
}
Time Memory Length Lang Submitted
187ms 27744kB 2369 G++ 2018-08-02 16:16:21

最新文章

  1. JBoss-7.1.1 http访问端口修改
  2. Winform 窗体控件随窗体自动(等比例)调整大小
  3. ie6下内容会撑开父级设置好的宽高
  4. Public and Private Interfaces in ruby
  5. K需要修改的内容
  6. linux基础命令学习(三)Vim使用
  7. 转载几篇关于GNU autotools的文章
  8. jQuery图片提示和文字提示
  9. Django学习系列之Form基础
  10. DevExpres表格控件运行时动态设置表格列
  11. JdbcTemplate 操作Oracle Blob
  12. SQL Server中日志
  13. [原创]Hadoop-2.5.2-HA原文译
  14. github上搜索资源
  15. NCE损失(Noise-Constrastive Estimation Loss)
  16. BZOJ1023:[SHOI2008]cactus仙人掌图(圆方树,DP,单调队列)
  17. LuoguP2161 [SHOI2009]会场预约
  18. iOS如何在iTunes网站查看并下载APP的dsym文件
  19. 正睿 2019 省选附加赛 Day1 T1 考考试
  20. openstack镜像制作思路、指导及问题总结

热门文章

  1. iOS开发-测量APP启动耗时
  2. Day 02 - 02 编程语言的分类
  3. failed to push some refs to &#39;git@github.com:RocsSun/mytest.git
  4. JS iframe给父类传值
  5. ElasticSearch启动报错,bootstrap checks failed
  6. IE9以下版本兼容h5标签
  7. C++ throw的实验 &amp; 异常类继承关系
  8. 为什么选性别会导致兴趣都选中-vue
  9. CF 567C(Geometric Progression-map)
  10. Button的Click事件与js函数的两种不同顺序触发方式