这里找到了两篇很nice的Trie树(作者Hackbuteer1)以及AC自动机(作者niushuai666)入门详解。博主写的可以说是非常用心了,一看就懂。

题意:给出N(<=10000)个单词(长度<=50)组成的字典。求串T(长度<=1e6)中出现了字典中的多少个单词。

题解:AC自动机裸题。所谓AC自动机就是Trie树加上了KMP的fail指针,而且是多模式的fail指针,意思就是说Trie图是有相同前缀的两个单词会有相同的一段root出发的路径,这个fail指针不再是KMP里某一个串的后缀和前缀相同并取最大,而是当前这个点得到的串的后缀和所有串中某个前缀相同且取最大。求这个fail就只要把KMP的过程改成广搜就行了,因为每个字符下一个状态可以是若干字符。。。每次把T中下一个字符考虑进来,通过fail指针转移到Trie图上的一个点上,然后统计root到这个点得到的串 的所有后缀的cnt(就是通过fail一点一点跳到根,把路径上的答案都统计起来。并把统计过的答案置为-1防止重复计数,同时fail跳到答案是-1的点表示这个点到根的答案已经统计过了,那么就提前停下来。)。

模板是我自己写的。。。可能比较丑。。。马上我会找一个好看的贴过来233

Code:

#include<bits/stdc++.h>
using namespace std;
const int MAX1 = 55;
const int MAX2 = 1000050;
char a[MAX1];
char b[MAX2];
struct ACAM {int id;int cnt;ACAM* fail;ACAM* nxt[26];
};
ACAM* root;
void ACAM_Clear(ACAM* root){for (int i=0;i<=25;i++){if (root->nxt[i]!=NULL){ACAM_Clear(root->nxt[i]);}}free(root);
};
ACAM* ACAM_Create(int id){ACAM* node = (ACAM*)(malloc(sizeof(ACAM)));node->cnt=0;node->fail = NULL;node->id =id;memset(node->nxt,0,sizeof(node->nxt));return node;
}
void ACAM_Insert(ACAM* root,char* word){ACAM* node = root;char* p = word;while (*p){int id = *p-'a';if (node->nxt[id]==NULL){node->nxt[id] = ACAM_Create(id);}node = node->nxt[id];p++; }node->cnt++;
}
ACAM* que[MAX2*10];
void ACAM_Build(ACAM* root){int l=0,r=0;for (int i=0;i<=25;i++){if (root->nxt[i]!=NULL){root->nxt[i]->fail = root;for (int j=0;j<=25;j++){if (root->nxt[i]->nxt[j]!=NULL){root->nxt[i]->nxt[j]->fail = root;r++;que[r] = root->nxt[i]->nxt[j];}}}}while (l<r){l++;ACAM* q = que[l];
//      printf("%d %c\n",l,q->id+'a');while (q->fail!=root&&q->fail->nxt[q->id]==NULL){q->fail = q->fail->fail;}if (q->fail->nxt[q->id]!=NULL){q->fail = q->fail->nxt[q->id];}
//      printf("%d fial = %c\n",l,q->fail->id+'a');for (int i=0;i<=25;i++){if (q->nxt[i]!=NULL){q->nxt[i]->fail = q->fail;r++;que[r] = q->nxt[i];}}}
}
int ACAM_Search(ACAM* root,char*word){int ans=0;ACAM* node = root;char* p = word;while (*p){
//      printf("%c\n",*p);int id = *p-'a';while (node->nxt[id]==NULL&&node!=root){node=node->fail;}if (node->nxt[id]!=NULL){node =  node->nxt[id];}ACAM* temp = node;while (temp!=root&&temp->cnt!=-1){ans+=temp->cnt;temp->cnt = -1;temp=temp->fail;}p++;}return ans;
}
void init(){ACAM_Clear(root);root = ACAM_Create(-1);
}
void input(){int n;scanf("%d",&n);while (n--){scanf("%s",a);ACAM_Insert(root,a);}
}
void solve(){ACAM_Build(root);scanf("%s",b);printf("%d\n",ACAM_Search(root,b));
}
int main(){int t;scanf("%d",&t);root = ACAM_Create(-1);while (t--){init();input();solve();}return 0;
} 

HDU 2222 ACAM模板(AC自动机)相关推荐

  1. HDU 2222 Keywords Search (AC自动机模板题)

    一组数据: 1 3 sss sss sss sss ans:3 #include <cstdio> #include <cstdlib> #include <vector ...

  2. hdu 2222 Keywords Search AC自动机——多串匹配

    http://acm.hdu.edu.cn/showproblem.php?pid=2222 题意: 给出n个单词,再给出一段包含m个字符的文章,求有多少个单词在文章里出现过. 思路: 才开开始以为简 ...

  3. HDU - 2222 Keywords Search(AC自动机)

    题目链接:点击查看 题目大意:给出n个长度不超过50的模式串,再给出一个长度不超过1e6的主串,问模式串在主串中出现过多少次 题目分析:一开始我以为是求n次KMP,后来才知道这样做的时间复杂度是O(L ...

  4. 模板 - AC自动机

    ACM-ICPC模板 目录 求有多少个模式串在文本串里出现过 建fail树dfs求每个模式串在文本串中的出现次数 ac自动机fail树上dfs序建可持久化线段树 AC自动机是一种多模匹配算法 AC自动 ...

  5. HDU 2896 病毒侵袭 AC自动机

    我表示不是很懂HDU卡内存的优良传统.......以及他们卡输出的良好风尚........ AC自动机裸体关键在于http://ascii.911cha.com/ #include<cstrin ...

  6. HDU 6208【假AC自动机+string方法】

    题目链接:http://acm.hdu.edu.cn/listproblem.php?vol=1 The Dominator of Strings Time Limit: 3000/3000 MS ( ...

  7. HDU - 2825 Wireless Password (AC自动机 + 状压dp)

    题目链接 题意 求至少包含KKK个给定字符串长度为NNN的字符串 思路 把所有可能的字符串建AC自动机,遍历所有节点dp[i][j][k]dp[i][j][k]dp[i][j][k] 表示以节点jjj ...

  8. HDU - 3247 Resource Archiver(AC自动机+状压dp+bfs)

    题目链接:点击查看 题目大意:给出 n 个目标串和 m 个病毒串,要求构造出一个长度最短的,且包含全部 n 个目标串,但是不能包含任意一个病毒串的01字符串,输出其最短长度 题目分析:比较综合的一道题 ...

  9. HDU - 2457 DNA repair(AC自动机+dp)

    题目链接:点击查看 题目大意:给出 n 个匹配串,再给出一个模式串,问最少修改模式串中多少个字母可以使得模式串中不含有任意一个匹配串 题目分析:因为又是模式串与匹配串的题目,虽然与一般意义上的匹配不太 ...

最新文章

  1. zencart安全辅助小脚本
  2. 【STM32】随机数发生器相关函数和类型
  3. Eclipse c++ 中[Linker error] undefined reference to `WSAStartup@8'的解决办法
  4. luoguP4213 【模板】杜教筛(Sum)杜教筛
  5. vue实现进度条隐藏_实现带有进度条的Vue延迟加载
  6. 怎么做软件安全性测试
  7. 修改CSDN博文中默认的图片水印
  8. 安卓-LBS地图显示
  9. mybatis sql语句格式化 trim prefix suffix
  10. Mono.Cecil说明文档翻译
  11. 自燃的特斯拉,渐失“民心”的电动车
  12. Android 中怎么重启APP、重启系统
  13. 为什么动漫比游戏建模精致?3大不同,一看就明白
  14. Win10显卡驱动在哪里?
  15. linux输入法大小,推荐linux下的输入法--五笔+拼音
  16. 专有钉钉 浙政钉 前端 对接流程(小程序)
  17. qos pre-classify
  18. JS checkbox
  19. SpringSecurity 源码解析 | 加JWT 实战 之 授权流程源码分析
  20. html下拉菜单省对应的市,javascript基于DOM实现省市级联下拉框的方法

热门文章

  1. python-进程调度_进程对象及方法_互斥锁_队列_IPC
  2. alibab仓库 idea_IntelliJ IDEA 超实用技巧分享,大大提高编程效率
  3. lncRNA最新研究进展盘点(2021年7月)
  4. 报错解决No implementation found for int包名+类名+方法名
  5. 肢体动作监测(WiFi通信)
  6. 【其他】Superchaeger注册码(激活码)
  7. kafkaConsumer的分区分配策略-实测说话
  8. x390拆机 升级内存和硬盘_苹果Mac mini拆解 内存和硬盘支持升级
  9. WebSocket菜鸟教程二
  10. 戴尔微型计算机特性,戴尔Latitude 9510评测:精湛的做工,不一样的智能使用体验...