HDU 5384 Danganronpa Posted on 2016-04-28 | In ACM | | Visitors 题目链接HDU 5384 方法:ac自动机 变形 题目分析题目大意n个字符串,m个子串,问每个字符串中有多少个子串,可以重复 解析ac自动机,但是删掉了查询时的一行代码,有待深入理解。 ac自动机详解链接 代码123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135#include <set>#include <map>#include <stack>#include <cmath>#include <queue>#include <cstdio>#include <string>#include <vector>#include <iomanip>#include <cstring>#include <iostream>#include <algorithm>#define Memset(a,val) memset(a,val,sizeof(a))#define PI acos(-1)#define rt(n) (i == n ? '\n' : ' ')#define hi printf("Hi----------\n")#define IN freopen("input.txt","r",stdin);#define OUT freopen("output.txt","w",stdout);#define debug(x) cout<<"Debug : ---"<<x<<"---"<<endl;#pragma comment(linker, "/STACK:1024000000,1024000000")typedef long long ll;using namespace std;const int maxn=1000+5;const int mod=1000000007;const int INF=0x3f3f3f3f;const double eps=1e-8;struct trie{ int next[500010][26],fail[500010],ed[500010]; int root,L; int newnode() { for(int i = 0; i < 26; i++) next[L][i] = -1; ed[L++] = 0; return L-1; } void init() { L = 0; root = newnode(); } void insert(char buf[]) { int len = strlen(buf); int now = root; for(int i = 0; i < len; i++) { if(next[now][buf[i]-'a'] == -1) next[now][buf[i]-'a'] = newnode(); now = next[now][buf[i]-'a']; } ed[now]++; } void build() { queue<int> q; fail[root] = root; for(int i = 0; i < 26; i++) if(next[root][i] == -1) next[root][i] = root; else { fail[next[root][i]] = root; q.push(next[root][i]); } while(!q.empty()) { int now = q.front(); q.pop(); for(int i = 0; i < 26; i++) if(next[now][i] == -1) next[now][i] = next[fail[now]][i]; else { fail[next[now][i]]=next[fail[now]][i]; q.push(next[now][i]); } } } int query(char buf[]) { int len = strlen(buf); int now = root; int res = 0; for(int i = 0; i < len; i++) { now = next[now][buf[i]-'a']; int temp = now; while(temp != root) { res += ed[temp]; temp = fail[temp]; } } return res; } void Debug() { for(int i = 0; i < L; i++) { printf("id = %3d,fail = %3d,end = %3d,chi = [",i,fail[i],ed[i]); for(int j = 0; j < 26; j++) printf("%2d",next[i][j]); printf("]\n"); } }};char buf[1000010];trie ac;char ss[100005][10005];int main(){ int t; int n,m; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); ac.init(); for (int i=0; i<n; i++) { scanf("%s",ss[i]); } for(int i = 0; i < m; i++) { scanf("%s",buf); ac.insert(buf); } ac.build(); for (int i=0; i<n; i++) { printf("%d\n",ac.query(ss[i])); } } return 0;}