标签:
// hdu 3065 AC自动机 // // 题目大意: // // 给你n个短串,然后给你一个长串,问:各个短串在长串中,出现了多少次 // // 解题思路: // // AC自动机,插入,构建,查询就OK啦 // // 感悟: // // 这道题真的是1A的哟~~~很开心~~~尽管是个裸地,继续加油哟~~~FIGHTING #include <cstdio> #include <cstring> #include <algorithm> #include <iostream> #include <queue> using namespace std; const int MAX_NODE = 200000; const int SIGMA = 131; struct Aho_Corasick{ int ch[MAX_NODE][SIGMA]; int f[MAX_NODE]; int val[MAX_NODE]; int last[MAX_NODE]; int cnt[1008]; int sz; void init(){ sz = 1; memset(ch[0],0,sizeof(ch[0])); memset(cnt,0,sizeof(cnt)); val[0] = 0; } void insert(char *s, int v){ int u = 0; int n = strlen(s); for (int i=0;i<n;i++){ int c = s[i]; if (!ch[u][c]){ memset(ch[sz],0,sizeof(ch[sz])); val[sz] = 0; ch[u][c] = sz++; } u = ch[u][c]; } val[u] = v; } void getfail(){ queue<int> que; for (int c = 0;c < SIGMA; c++){ int u = ch[0][c]; if(u){ que.push(u); f[u] = 0; last[u] = 0; } } while(!que.empty()){ int r = que.front(); que.pop(); for (int c = 0 ; c < SIGMA;c++){ int u = ch[r][c]; if (!u) continue; que.push(u); int v = f[r]; while( v && !ch[v][c]) v = f[v]; f[u] = ch[v][c]; last[u] = val[f[u]] ? f[u] : last[f[u]]; } } } void get_cnt(int u){ if (u){ cnt[val[u]]++; get_cnt(last[u]); } } void query(char *s){ int u = 0; int n = strlen(s); for(int i=0;i<n;i++){ int c = s[i]; while(u && !ch[u][c]) u = f[u]; u = ch[u][c]; if (val[u]){ get_cnt(u); }else if (last[u]){ get_cnt(last[u]); } } } }ac; int n; char p[1008][52]; char str[2000008]; void input(){ ac.init(); char s[52]; for (int i=1;i<=n;i++){ scanf("%s",s); memcpy(p[i],s,sizeof(s)); ac.insert(s,i); } ac.getfail(); scanf("%s",str); ac.query(str); for (int i = 1;i<=n;i++){ if (ac.cnt[i]){ printf("%s: %d\n",p[i],ac.cnt[i]); } } } int main(){ //freopen("1.txt","r",stdin); while(scanf("%d",&n)!=EOF){ input(); } return 0; }
标签:
原文地址:http://www.cnblogs.com/KingJourney/p/4703400.html