hdu 2222 AC自动机学校

#include <iostream>
#include <stdio.h>
#include <queue>
using namespace std;
const int maxn=(int)1e6+10;
const int maxm=(int)5e5+10;
struct trie{
int nxt[maxm][26],fail[maxm],ed[maxm];
int rt,l;
int newnod(){
for(int i=0;i<26;i++)nxt[l][i]=-1;
ed[l++]=0;
return l-1;
}
void init(){
l=0;rt=newnod();
}
void inset(char s[]){
int now=rt;
for(int i=0;s[i];i++){
if(nxt[now][s[i]-‘a‘]==-1)nxt[now][s[i]-‘a‘]=newnod();
now=nxt[now][s[i]-‘a‘];
}
ed[now]++;
}
void build(){
static queue<int>q;fail[rt]=rt;

for(int i=0;i<26;i++)
if(nxt[rt][i]==-1)nxt[rt][i]=rt;
else{
fail[nxt[rt][i]]=rt;q.push(nxt[rt][i]);
}
while(!q.empty()){
int now=q.front();
q.pop();
for(int i=0;i<26;i++){
if(nxt[now][i]==-1) nxt[now][i]=nxt[fail[now]][i];
//如果当前单词的下一个字母结点为空,当前单词的该字母结点指
//向fail结点的对应字母结点
else{
//如果当前单词的下一个字母结点不为空,当前单词的该字母结点的fail结点
//指向fail结点的对应字母结点
fail[nxt[now][i]]=nxt[fail[now]][i];
q.push(nxt[now][i]);
}
}
}
}
//fail[i]即i结点所在单词以i结点为结尾和其它单词中以i结点代表字母为结尾的公共最长后前缀的结点
int query(char s[]){
int now=rt,res=0;
for(int i=0;s[i];i++){
now=nxt[now][s[i]-‘a‘];
//新start=上一个start的s[i]字母结点的nxt指向结点,单词存在就指向单词下一个字母,
//不存在指向别的单词的该字母,就指向fail[st]的nxt指向结点
//
int tmp=now;
printf("s[%d]: %c tmp :%d now:%d\n",i,s[i],tmp,now);
while(tmp!=rt){

if(ed[tmp]==1)printf("--%d\n",tmp);
res+=ed[tmp];ed[tmp]=0;tmp=fail[tmp];
printf("tmp:%d\n",tmp);
}
}
return res;
}
void debug(){
printf("id = %3d fail = %3d ed= %3d chi = [",0,0,0);
for(int j=0;j<26;j++)printf("%2c",‘a‘+j);printf("\n");
for(int i=0;i<l;i++){
printf("id = %3d fail = %3d ed= %3d chi = [",i,fail[i],ed[i]);
for(int j=0;j<26;j++)printf("%2d",nxt[i][j]);printf("\n");
}
}

};
char s[maxn];
trie ac;

void dfs(int st,string tmp=""){
if(ac.ed[st]!=0) cout<<tmp<<endl;
for(int i=0;i<26;i++){
if(ac.nxt[st][i]!=-1) dfs(ac.nxt[st][i],tmp+(char)(‘a‘+i));
}
}
void dfs1(int st,string tmp=""){
if(ac.ed[st]!=0) cout<<tmp<<endl;
for(int i=0;i<26;i++){
if(ac.nxt[st][i]!=0) dfs(ac.nxt[st][i],tmp+(char)(‘a‘+i));
}
}
int main()
{
#ifdef shuaishuai
freopen("C:\\Users\\hasee\\Desktop\\a.txt","r",stdin);
//freopen("C:\\Users\\hasee\\Desktop\\b.txt","w",stdout);
#endif
int T,n;
scanf("%d",&T);
while(T--){
scanf("%d",&n);
ac.init();
for(int i=0;i<n;i++){
scanf("%s",s);
ac.inset(s);
}

// dfs(0);
ac.debug();
ac.build();
// dfs1(0);
// for(int i=0;i<ac.l;i++)
// { printf("%d\n",ac.ed[i]);
// for(int j=0;j<26;j++)printf("%d ",ac.nxt[i][j]);
// printf("\n");
// }
ac.debug();
scanf("%s",s);
printf("%d\n",ac.query(s));
}
return 0;
}

时间: 2024-10-20 07:53:28

hdu 2222 AC自动机学校的相关文章

HDU 2222 AC自动机模板题

题目: http://acm.hdu.edu.cn/showproblem.php?pid=2222 AC自动机模板题 1 #include<stdio.h> 2 #include<string.h> 3 #include<queue> 4 using namespace std; 5 char key[55]; 6 char des[1111111]; 7 struct node{ 8 node *fail; 9 node *next[26]; 10 int cnt;

HDU 2222 ----AC自动机

Problem Description In the modern time, Search engine came into the life of everybody like Google, Baidu, etc.Wiskey also wants to bring this feature to his image retrieval system.Every image have a long description, when users type some keywords to

hdu 2222 AC自动机(可做模板)

Keywords Search Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 50101    Accepted Submission(s): 16083 Problem Description In the modern time, Search engine came into the life of everybody li

hdu 2222 AC自动机(模板题)

<题目链接> 题目大意: 给你一些单词,和一个字符串,问你这个字符串中含有多少个上面的单词. 解题分析: 这是多模匹配问题,如果用KMP的话,对每一个单词,都跑一遍KMP,那么当单词数量非常多的时候,耗时会非常多,所以这里用到了AC自动机,这是一种类似于Trie树的数据结构,但是同时,它也用到了KMP算法中 next数组的思想. 下面是AC自动机指针形式的题解: #include <stdio.h> #include <stdlib.h> #include <st

HDU 2222 AC自动机(模版题)

Keywords Search Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 70290    Accepted Submission(s): 23917 Problem Description In the modern time, Search engine came into the life of everybody lik

hdu 2896 AC自动机

// hdu 2896 AC自动机 // // 题目大意: // // 给你n个短串,然后给你q串长字符串,要求每个长字符串中 // 是否出现短串,出现的短串各是什么 // // 解题思路: // // AC自动机,插入单词,构建自动机,然后查询就可以了. // // 感悟: // // 哎,自己AC自动机果然刚学,还只会个模板,自动机构没构建 // 都不知道...继续加油吧~~~FIGHTING! #include <cstdio> #include <cstring> #inc

hdu 2296 aC自动机+dp(得到价值最大的字符串)

Ring Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 3180    Accepted Submission(s): 1033 Problem Description For the hope of a forever love, Steven is planning to send a ring to Jane with a rom

hdu 2457 AC自动机+dp

DNA repair Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2004    Accepted Submission(s): 1085 Problem Description Biologists finally invent techniques of repairing DNA that contains segments c

hdu 2825 aC自动机+状压dp

Wireless Password Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 5640    Accepted Submission(s): 1785 Problem Description Liyuan lives in a old apartment. One day, he suddenly found that there