HDU 3695 浅谈AC自动机模式串匹配算法+严格空间控制
来源:互联网 发布:2016网络彩票重启时间 编辑:程序博客网 时间:2024/06/07 08:41
世界真的很大
日常被数组坑233
感觉怎么也调不出来的时候就去看一下是不是空间的问题吧。。
HDU的题日常多组数据。。
每组数据用完不清零基本上MLE
看题先:
description:
给出很多个模式串,问在文章里有几个模式串,(反过来的模式串也算)出现过文章里有时会有形如[n X]的东西,n是数字,X是字符,表示这个位置有n个X字符n不一定是一位数
input:
多组数据,每组数据开头一个数字n,表示有n个模式串接下来n行,每行一个模式串然后一个字符串给出文章
output:
每组数据一个数字表示有都是个模式串出现过
基本上还算是AC自动机的裸题,为了复习AC自动机的写法去做的,却意外的调了半天,忽然觉得还是写一下比较好
首先考虑怎么处理模式串反过来也算的问题
就直接反过来再插入就好
但是这两个串都出现也只能算一个串出现了,所以考虑给trie树里面每个串打标记,标记其属于哪个模式串
然后处理文章里面[]的问题。
还是比较简单,注意一下细节就好
数组记得开大一点,字符串开5100010
我就是数组开小了,WA了半天。。他不RE,WA。。
完整代码:
#include<stdio.h>#include<cstring>#include<queue>#include<algorithm>using namespace std;struct node{ node *fail; node *nxt[26]; int cnt,mrk,idc;}pool[10000010],*tail=pool,*root;int n,T,vis[8000010];char t[5100010],ss[5100010],sss[5100010];node *newnode(){ node *nd=++tail; memset(nd->nxt,0,sizeof(nd->nxt)); nd->fail=0; nd->cnt=nd->mrk=nd->idc=0; return nd;}void init(){ memset(ss,0,sizeof(ss)); memset(t,0,sizeof(t)); memset(sss,0,sizeof(sss)); memset(vis,0,sizeof(vis)); tail=pool; root=newnode();}void insert(char *s,int id){ int len=strlen(s); node *p=root; for(int i=0;i<len;i++) { int k=s[i]-'A'; if(!p->nxt[k]) p->nxt[k]=newnode(); p=p->nxt[k]; } p->cnt++; p->idc=id;}void build(){ queue <node*> state; state.push(root); root->fail=0; while(!state.empty()) { node *tmp=state.front(),*p=0; state.pop(); for(int i=0;i<26;i++) if(tmp->nxt[i]) { if(tmp==root) tmp->nxt[i]->fail=root; else { p=tmp->fail; while(p) { if(p->nxt[i]) { tmp->nxt[i]->fail=p->nxt[i]; break ; } p=p->fail; } if(!p) tmp->nxt[i]->fail=root; } state.push(tmp->nxt[i]); } }}void trans(char *s){ int i; int j=0,num=0; for(i=0;s[i];i++){ if('A'<=s[i] && s[i]<='Z') ss[j++] = s[i]; else if( '0'<=s[i] && s[i]<='9') num = num*10 + int(s[i]-'0'); else if( s[i]==']' ) while(--num) ss[j++] = s[i-1]; } ss[j] = '\0';}void query(char *s){ int cnt=0,k,len=strlen(s); node *p=root; for(int i=0;i<len;i++) { k=s[i]-'A'; while(!p->nxt[k] && p!=root) p=p->fail; p=p->nxt[k]; if(!p) p=root; node *tmp=p; while(tmp!=root&& !tmp->mrk) { tmp->mrk=1; if(tmp->idc>0) vis[tmp->idc]=1; tmp=tmp->fail; } }}int getans(){ int rt=0; for(int i=1;i<=n;i++) rt+=vis[i]; return rt;}int main(){ scanf("%d",&T); while(T--) { init(); scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%s",t); insert(t,i); reverse(t,t+strlen(t)); insert(t,i); } build(); scanf("%s",sss); trans(sss);query(ss); printf("%d\n",getans()); } return 0;}/*Whoso pulleth out this sword from this stone and anvil is duly born King of all England*/
嗯,就是这样
阅读全文
0 0
- HDU 3695 浅谈AC自动机模式串匹配算法+严格空间控制
- HDU 2896 AC自动机 模式串匹配
- HDU 2896 病毒入侵 AC自动机 多模式串匹配
- 多模式匹配--AC自动机算法
- AC自动机-多模式匹配算法
- AC自动机 多模式串匹配 模板
- 多模式匹配算法:AC自动机的C++实现
- Aho-Corasick 多模式匹配算法、AC自动机详解
- Aho-Corasick 多模式匹配算法、AC自动机详解
- hdu 2222 ac自动机 模式串计数
- HDU-3695-ac自动机
- hdu 3695 ac自动机
- hdu 3695 ac自动机
- HDU 3695 (AC自动机)
- hdu 3065 AC自动机 匹配串编号以及出现次数
- AC自动机——多模式串的匹配
- 多串匹配-AC自动机
- 多串匹配 AC自动机
- 让html标签以正常文本显示(评论模块中防止用户提交恶意的html或javascipt代码)
- 如何访问虚拟机中的架设的Web服务器(解决方法)
- Android6.0FileOutputStream写入文件问题
- 在ArcGIS属性表中如何添加百分号%特殊字符
- HTML textarea输入框提示文字,添加默认内容
- HDU 3695 浅谈AC自动机模式串匹配算法+严格空间控制
- (剑指offer)数组中任意一个重复的数字
- TYVJ 4868 天天和不可描述 || 清北学堂金秋杯大奖赛
- scala for循环
- 上传图片实现
- 《项目经验》——各类 HTTP 返回状态码原因以及解决办法
- Jquery中each的三种遍历方法
- HDU3338 Kakuro Extension【网络流】
- PullToRefreshListView今日头条初始页面 补充