Description
A string is a finite sequence of symbols that are chosen from an alphabet. In this problem you are given a string T and n queries each with a stringPi, where the strings contain lower case English alphabets only. You have to find the number of times Pi occurs as a substring of T.
Input
Input starts with an integer T (≤ 10), denoting the number of test cases.
Each case starts with a line containing an integer n (1 ≤ n ≤ 500). The next line contains the string T (1 ≤ |T| ≤ 106). Each of the next n lines contains a string Pi (1 ≤ |Pi| ≤ 500).
Output
For each case, print the case number in a single line first. Then for each string Pi, report the number of times it occurs as a substring of T in a single line.
Sample Input
2
5
ababacbabc
aba
ba
ac
a
abc
3
lightoj
oj
light
lit
Sample Output
Case 1:
2
3
1
4
1
Case 2:
1
1
0
题意:裸的AC自动机,问一篇文章中给出的匹配串各出现多少次。
一直wa一直wa,拿壕的代码测试每个代码块却都可以AC,单个测部分测都可以AC......于是开始怀疑人生= =...
崩溃边缘发现是答案数组开小了,导致一直wa。
一个数组就搞得整个代码都过不了,嗯...莫名好难过..........
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <algorithm>
#include <queue>
#include <stack>
#include <iostream>
#include <assert.h>
#define INF 0x3f3f3f3f
using namespace std;
const int M = 1e6 + 10;
const int SIZE = 30;
const int N = 3e5 + 10;
const int MAXN = 510;
char str[MAXN][MAXN];
int tricnt;
int ch[N][SIZE];
int fails[N];
int ed[N];
//bool vis[N];
char txt[M];
int ans[N]; //就是这个数组!!!!!!wa了我一下午...........
int newnode()
{
memset(ch[tricnt], 0, sizeof(ch[tricnt]));
fails[tricnt] = 0;
ed[tricnt] = 0;
//vis[tricnt] = false;
return tricnt++;
}
void init()
{
tricnt = 0;
newnode();
}
int trinsert(char* s)
{
int u = 0;
int len = strlen(s);
int v;
for (int i = 0; i < len; i++) {
v = s[i] - 'a';
if (!ch[u][v])
ch[u][v] = newnode();
u = ch[u][v];
}
ed[u] = 1;
//cout << u << "~" << ed[u] << endl;
return u;
}
void getfail()
{
queue<int> q;
for (int i = 0; i < SIZE; i++)
if (ch[0][i])
q.push(ch[0][i]);
while (!q.empty()) {
int r = q.front();
q.pop();
for (int i = 0; i < SIZE; i++) {
int v = ch[r][i];
if (v) {
q.push(v);
int u = fails[r];
while (u && !ch[u][i])
u = fails[u];
fails[v] = ch[u][i];
}
else ch[r][i] = ch[fails[r]][i];
}
}
}
int query(char* s)
{
getfail();
int u = 0;
int p, v;
for (int i = 0; s[i]; i++) {
v = s[i] - 'a';
//while (u && !ch[u][v]) u = fails[u];
u = ch[u][v];
p = u;
while (p) {
if (ed[p]) {
ans[p]++;
//vis[p] = true;
}
p = fails[p];
}
}
}
int main()
{
int T;
cin >> T;
for (int casecnt = 1; casecnt <= T; casecnt++) {
int n;
scanf("%d", &n);
init();
memset(ans, 0, sizeof(ans));
scanf("%s", txt);
for (int i = 0; i < n; i++) {
scanf("%s", str[i]);
trinsert(str[i]);
}
query(txt);
printf("Case %d:\n", casecnt);
for (int i = 0; i < n; i++) {
printf("%d\n", ans[trinsert(str[i])]);
}
}
return 0;
}