您的位置:首页 > 产品设计 > UI/UE

LightOJ - 1427 - Substring Frequency (II)(AC自动机)

2016-08-05 18:59 351 查看
J - Substring Frequency (II)

Time Limit:5000MS     Memory
Limit:
131072KB     64bit IO Format:%lld
& %llu
Submit Status

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
[SIZE];
int fails
;
int ed
;
//bool vis
;
char txt[M];
int ans
; //就是这个数组!!!!!!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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: