HDU-3065 病毒侵袭持续中 AC自动机!
2017-01-13 08:58
519 查看
病毒侵袭持续中
上一题是求出现多少病毒输出病毒序号,而这题输出每个病毒出现的次数。这题有字典树基础都能做出来,把叶子节点用相应的编号标记起来,匹配的时候遍历到叶子节点用一个数组把次数存起来就行了。有了前几题的教训直接用静态树做用C++交,果然不会错!
const int N=129; char str[2000001],s[1001][55],v[1001]; int head,tail,cnt; struct tree { int f; tree *fail; tree *next ; }*q[50001],*root,memory[50001]; void insert(int i,char *s) { tree *p=root; while(*s!='\0') { int id=(int)(*s); if(p->next[id]==NULL) p->next[id]=&memory[cnt++]; p=p->next[id]; s++; } p->f=i; } void build() { root->fail=NULL; q[head++]=root; while(head!=tail) { tree *temp=q[tail++]; tree *p=NULL; for(int i=0; i<N; i++) if(temp->next[i]) { if(temp==root) temp->next[i]->fail=root; else { p=temp->fail; while(p!=NULL) { if(p->next[i]) { temp->next[i]->fail=p->next[i]; break; } p=p->fail; } if(p==NULL) temp->next[i]->fail=root; } q[head++]=temp->next[i]; } } } void find(char *s) { tree *p=root; int ans=0; while(*s!='\0') { int id=(int)(*s); while(p->next[id]==NULL&&p!=root) p=p->fail; p=p->next[id]; p=p==NULL?root:p; tree *temp=p; while(temp!=root) { if(temp->f) v[temp->f]++; temp=temp->fail; } s++; } } int main() { int n; while(~scanf("%d",&n)) { memset(memory,0,sizeof(memory)); memset(v,0,sizeof(v)); cnt=head=tail=0; root=&memory[cnt++]; for(int i=1; i<=n; i++) { scanf("%s",s[i]); insert(i,s[i]); } build(); scanf("%s",str); find(str); for(int i=1; i<=n; i++) if(v[i]) printf("%s: %d\n",s[i],v[i]); } return 0; }
相关文章推荐
- 最全解析:支付宝钱包系统架构内部揭秘
- 使用highcharts显示mongodb中的数据
- Angular2 倒计时组件
- c:if 通过${fn:contains(id,'')多条件判断
- 【Java每日一题】20170113
- 2149 矩形周长
- 0119
- 连接SQL Server 2008 R2 error 40处理方法
- 擅长排列的小明 II
- .NET框架-Try-Parse和Tester-Doer
- C++基础:标准输入输出
- 电脑屏幕亮度能否自动调节
- Linux挂载u盘
- C++学习笔记
- 【Java每日一题】20170113
- /sys/kernel/debug/gpio
- BZOJ 3166 set+可持久化trie树(OR 莫队)
- jquery,js简单实现类似Angular.js双向绑定
- 译]badblocks指令
- mypipe使用中出现的null:4问题