题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5384
题意:函数f(A, B)定义:A、B为字符串,f(A, B)为A中有多少个不同的B(ex:f("ababa", "aba")==2 f("ababa", "bab")==1),现在给你一组A串,一组B串,问你对每个A串的是多少
解:ac自动机模板题,可以把A串用'z'+1,连成一个串处理起来比较方便
1 /* 2 * Problem: hdu5384 Danganronpa 3 * Author: SHJWUDP 4 * Created Time: 2015/8/13 星期四 14:38:23 5 * File Name: 1006.cpp 6 * State: Accepted 7 * Memo: ac自动机 8 */ 9 #include <iostream> 10 #include <cstdio> 11 #include <vector> 12 #include <cstring> 13 #include <algorithm> 14 #include <queue> 15 16 using namespace std; 17 18 const int MaxA=1e5+7; 19 const int MaxB=7e5+7; 20 21 const int SIGMA_SIZE=27; 22 23 struct AhoCorasickAutomata { 24 int ch[MaxB][SIGMA_SIZE]; 25 int val[MaxB]; 26 int sz; 27 int f[MaxB], last[MaxB]; 28 29 int newNode() { 30 memset(ch[sz], 0, sizeof(ch[sz])); 31 val[sz]=0; 32 return sz++; 33 } 34 35 void init() { 36 sz=0; 37 newNode(); 38 } 39 40 int id(char c) { 41 return c-'a'; 42 } 43 44 void insert(char* p) { 45 int u=0; 46 while(*p) { 47 int c=id(*p++); 48 if(!ch[u][c]) ch[u][c]=newNode(); 49 u=ch[u][c]; 50 } 51 val[u]++; 52 } 53 54 void getFail() { 55 queue<int> Q; 56 f[0]=0; 57 for(int c=0; c<SIGMA_SIZE; c++) { 58 int u=ch[0][c]; 59 if(u) { f[u]=0; Q.push(u); last[u]=0; } 60 } 61 62 while(!Q.empty()) { 63 int r=Q.front(); Q.pop(); 64 for(int c=0; c<SIGMA_SIZE; c++) { 65 int u=ch[r][c]; 66 if(!u) { ch[r][c]=ch[f[r]][c]; continue; } 67 Q.push(u); 68 int v=f[r]; 69 while(v && !ch[v][c]) v=f[v]; 70 f[u]=ch[v][c]; 71 last[u]=val[f[u]]?f[u]:last[f[u]]; 72 } 73 } 74 } 75 76 long long dealAns(int u) { 77 long long res=0; 78 while(u) { 79 res+=val[u]; 80 // val[u]=0; 81 u=last[u]; 82 } 83 return res; 84 } 85 86 void find(char * T, long long * ans) { 87 int u=0; 88 int pos=1; 89 long long sum=0, ltsum=0; 90 for(int i=0; T[i]; i++) { 91 int c=id(T[i]); 92 u=ch[u][c]; 93 if(val[u]) sum+=dealAns(u); 94 else if(last[u]) sum+=dealAns(last[u]); 95 if(T[i]=='z'+1) { 96 ans[pos++]+=sum-ltsum; 97 ltsum=sum; 98 } 99 } 100 } 101 } ac; 102 103 int n, m; 104 char str[MaxB]; 105 long long ans[MaxA]; 106 char gogogo[MaxA]; 107 int main() { 108 #ifndef ONLINE_JUDGE 109 freopen("in", "r", stdin); 110 //freopen("out", "w", stdout); 111 #endif 112 int T; 113 scanf("%d", &T); 114 while(T--) { 115 scanf("%d%d", &n, &m); 116 int len=0; 117 for(int i=0; i<n; i++) { 118 scanf("%s", str+len); 119 while(str[len]) len++; 120 str[len++]='z'+1; 121 } 122 str[len]='\0'; 123 ac.init(); 124 for(int i=0; i<m; i++) { 125 scanf("%s", gogogo); 126 ac.insert(gogogo); 127 } 128 ac.getFail(); 129 memset(ans, 0, sizeof(ans)); 130 ac.find(str, ans); 131 for(int i=1; i<=n; i++) { 132 printf("%I64d\n", ans[i]); 133 } 134 } 135 return 0; 136 }