hdu 5384 Danganronpa(AC自动机模板题)
2015-08-28 16:43
375 查看
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=5384
解题思路:
题目大意:
给你n个字符串主串,和m个模式串,定义f(A,B)为B串在A串中出现的次数,现在对每一个A串都计算∑f(Ai,Bj) (1 <= j <= m),并输出。
对m个模式串建立AC自动机,然后每个主串都放入自动机中,统计主串包含多少B内的串,并输出。
算法思想:
AC自动机的模板题。。。
注意:
标记的时候直接累加值,可能会有多个模式串相同。
AC代码(fail指针):
AC代码(next数组):
http://acm.hdu.edu.cn/showproblem.php?pid=5384
解题思路:
题目大意:
给你n个字符串主串,和m个模式串,定义f(A,B)为B串在A串中出现的次数,现在对每一个A串都计算∑f(Ai,Bj) (1 <= j <= m),并输出。
对m个模式串建立AC自动机,然后每个主串都放入自动机中,统计主串包含多少B内的串,并输出。
算法思想:
AC自动机的模板题。。。
注意:
标记的时候直接累加值,可能会有多个模式串相同。
AC代码(fail指针):
#include <iostream> #include <cstdio> #include <cstring> #include <string> #define N 100005 #define L 10005 using namespace std; int n,m; char str [L], keyword[L]; int head, tail; struct node { node *fail; node *next[26]; int cnt; node() //init { fail = NULL; cnt = 0; for(int i = 0; i < 26; ++i) next[i] = NULL; } }*q ; node *root; void Insert(char *str) //建立Trie { int temp, len; node *p = root; len = strlen(str); for(int i = 0; i < len; ++i) { temp = str[i] - 'a'; if(p->next[temp] == NULL) p->next[temp] = new node(); p = p->next[temp]; } p->cnt++; } void build_ac() //初始化fail指针,BFS { q[tail++] = root; while(head != tail) { node *p = q[head++]; //弹出队头 node *temp = NULL; for(int i = 0; i < 26; ++i) { if(p->next[i] != NULL) { if(p == root) //第一个元素fail必指向根 p->next[i]->fail = root; else { temp = p->fail; //失败指针 while(temp != NULL) //2种情况结束:匹配为空or找到匹配 { if(temp->next[i] != NULL) //找到匹配 { p->next[i]->fail = temp->next[i]; break; } temp = temp->fail; } if(temp == NULL) //为空则从头匹配 p->next[i]->fail = root; } q[tail++] = p->next[i]; //入队 } } } } int query(char *str) //扫描 { int index, len, result; node *p = root; //Tire入口 result = 0; len = strlen(str); for(int i = 0; i < len; ++i) { index = str[i] - 'a'; while(p->next[index] == NULL && p != root) //跳转失败指针 p = p->fail; p = p->next[index]; if(p == NULL) p = root; node *temp = p; //p不动,temp计算后缀串 while(temp != root && temp->cnt != -1) { result += temp->cnt; //temp->count = -1; temp = temp->fail; } } return result; } int main() { int T; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); head= tail = 0; root = new node(); for(int i = 0; i < n; i++) scanf("%s",str[i]); for(int i = 0; i < m; i++) { scanf("%s",keyword); Insert(keyword); } build_ac(); for(int i = 0; i < n; i++) printf("%d\n",query(str[i])); } return 0; }
AC代码(next数组):
#include <iostream> #include <cstdio> #include <queue> #define L 10010 using namespace std; struct node{ int d; int num; }; int n,m; char str[10005][L]; char keyword[L]; int Next[100005][26],fail[100005],pos; int cnt[100005]; int newnode() { for(int i=0; i<26; i++) Next[pos][i] = 0; fail[pos] = cnt[pos] = 0; return pos++; } void Insert(char *s) //构造trie { int i,p = 0; for(i=0; s[i]; i++) { int k = s[i] - 'a', &x = Next[p][k]; p = x?x : x = newnode(); } cnt[p]++; // 位运算要用 } void makeNext() // 构造失败指针 { int i; queue<int>q; q.push(0); while(!q.empty()) { int u = q.front(); cnt[u] += cnt[fail[u]]; q.pop(); for(i=0; i<26; i++) { int v = Next[u][i]; if(v == 0) Next[u][i] = Next[fail[u]][i]; else q.push(v); if(u && v) { fail[v]=Next[fail[u]][i]; } } } } int query(char *s) { int ret = 0; int idx, d = 0; node tmp; for(int i=0; s[i]; i++) { idx = s[i] - 'a'; d = Next[d][idx]; ret += cnt[d]; //cnt[d] = 0; } return ret; } int main() { int T; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); pos = 0; newnode(); for(int i = 0; i < n; i++) scanf("%s",str[i]); for(int i = 0; i < m; i++) { scanf("%s",keyword); Insert(keyword); } makeNext(); for(int i =0; i < n; i++) printf("%d\n",query(str[i])); } return 0; }
相关文章推荐
- 学习资料
- DatePickerDialog、TimePickerDialog、PopupWindow、Notification
- [原创]Linux下使用Daemon实现服务器永久存活
- 深入理解计算机操作系统——第9章:缓存,存储器管理
- 补题列表
- 【JavaScript基础知识】——面向对象和原型
- Mars Chen动态注册Broadcast广播监听器的实现
- 最火的UI快速开发框架androidannotations
- 待学技术或框架
- zzuli OJ 1067: 有问题的里程表
- eclipse导入或新建工程出错解决方案
- Ansj标准分词使用注意事项(MyStaticValue.isRealName属性)
- 《PCI EXPRESS体系结构导读》读书笔记之PCI总线的存储器读写总线事务
- 简介:块存储、文件存储、对象存储
- 【原创】boost::recursive_mutex请小心使用
- Sqlite事物与锁
- LeetCode-Ugly Number-解题报告
- IO中 mark 和reset 的使用
- excel文件太大的九大原因
- zzuli OJ 1066: 字符分类统计