初识AC自动机 HDU2222
来源:互联网 发布:二维数组回形遍历 编辑:程序博客网 时间:2024/05/29 19:07
做了一天了,看懂了AC自动机的原理,纯属脑洞码了一天~
几个小函数解释如下:
- insert即trie树建立的过程
- KMP是找到trie树中的每个节点的后缀节点,和一维的字符串差不多
- find(x,d)是找到x结点下经过字符d转化到的下一个结点,可能会出现没有的情况,标记为0,即重新返回根节点
HDU2222
注意点:
- 若关键字A与关键字B重复,在主串中出现一个算两次
- 若关键字A在主串种出现两次,则只算一次
- 在主串经过的每个结点,都访问该节点的后缀节点,看其是否是终止结点。
- 访问过的一系列后缀节点可以做标记,下次访问无需再重新累加。
#include <cstdio>#include <iostream>#include <cstring>#include <queue>#include <algorithm>using namespace std;int ans, size;struct node{char ch;int next[26], fa, end, pre, have;void pr(){printf("%c %d %d %d\n", ch, fa, pre, end);}}tree[250005];char str[10001][51];void insert(char *key){char *p = key;int s = 0;while(*p){if(!tree[s].next[*p-'a'])tree[s].next[*p-'a'] = ++size;int t = s;s = tree[s].next[*p-'a'];tree[s].fa = t;tree[s].ch = *p;p++;}tree[s].end++;//repeated key words can be calculated more than once}int find(int x, char d){return tree[x].next[d-'a'];}void KMP(char *key){char *p = key;int s = find(0, *p);tree[s].pre = 0;p++;while(*p){int i = s;s = find(s, *p);//printf("%d %c\n", s, *p);int j = tree[i].pre;while(j > 0 && !find(j, *p))j = tree[j].pre;tree[s].pre = find(j, *p);p++;}}int sig(int x)//visit x, x.pre, x.pre.pre, ....{//printf("sig tree[%d] have %d pre %d end %d\n", //x, tree[x].have, tree[x].pre, tree[x].end);if(!x)return 0;if(tree[x].have)return 0;tree[x].have = 1;return tree[x].end + sig(tree[x].pre);}int main(){int T, n;scanf("%d", &T);while(T--){memset(tree, 0, sizeof(tree));ans = size = 0;scanf("%d", &n);for(int i = 0;i < n;i++){scanf("%s", str[i]);insert(str[i]);}tree[0].pre = 0;for(int i = 0;i < n;i++)KMP(str[i]);/*for(int i = 0;i <= size;i++){printf("tree[%d] ", i);tree[i].pr();}*/char c;int s = 0;getchar();while((c = getchar()) != '\n'){//printf("this %c ", c);while(s > 0 && !tree[s].next[c-'a']){s = tree[s].pre;ans += sig(s);}if(tree[s].next[c-'a']){ans += sig(s);s = tree[s].next[c-'a'];}ans += sig(s);//printf("s %d ans %d\n", s, ans);}printf("%d\n", ans);}return 0;}
0 0
- 初识AC自动机 HDU2222
- hdu2222 ac自动机模版
- hdu2222 AC自动机
- hdu2222,(ac自动机)
- HDU2222-tire,AC自动机
- AC自动机模板 hdu2222
- hdu2222-AC自动机
- HDU2222 AC自动机
- hdu2222 AC自动机
- 【AC自动机】HDU2222
- hdu2222 AC自动机
- hdu2222 ac自动机。。。。
- HDU2222 AC自动机入门
- hdu2222 ac自动机模板
- hdu2222 AC自动机
- hdu2222(AC自动机入门)
- AC自动机 hdu2222
- HDU2222 AC自动机模板
- MySQL修改root密码的多种方法
- Java文件操作 file类层级显示目录
- credit risk 预测建模 - try 1
- PHP学习书籍记录
- 《学习OpenCV》第四章课后题5-a
- 初识AC自动机 HDU2222
- 【linux】RocketMQ:一个纯java的开源消息中间件--开发测试环境搭建
- ssh远程调用之shell脚本远程调用应用程序
- 将汉字转化为拼音
- cocoapods的安装,使用,卸载,以及你可能会遇到的坑..
- 【JAVA程序】猜拳游戏
- docker swarm集群TLS配置
- WCF 配置服务 (02)
- poj2912 带权并查集,类似食物链