# BZOJ2780 [Spoj]8093 Sevenk Love Oimaster 【广义后缀自动机】

## 题目

 Oimaster and sevenk love each other.

But recently,sevenk heard that a girl named ChuYuXun was dating with oimaster.As a woman's nature, sevenk felt angry and began to check oimaster's online talk with ChuYuXun.    Oimaster talked with ChuYuXun n times, and each online talk actually is a string.Sevenk asks q questions like this,    "how many strings in oimaster's online talk contain this string as their substrings?"


## 输入格式

There are two integers in the first line,
the number of strings n and the number of questions q.
And n lines follow, each of them is a string describing oimaster's online talk.
And q lines follow, each of them is a question.
n<=10000, q<=60000
the total length of n strings<=100000,
the total length of q question strings<=360000

## 输出格式

For each question, output the answer in one line.

3 3

abcabcabc

aaa

aafe

abc

a

ca

1

3

1

## 题解

#include<iostream>
#include<cstdio>
#include<cmath>
#include<string>
#include<cstring>
#include<algorithm>
#define LL long long int
#define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define BUG(s,n) for (int i = 1; i <= (n); i++) cout<<s[i]<<' '; puts("");
using namespace std;
const int maxn = 200005,maxm = 400005,INF = 1000000000;
int out = 0,flag = 1; char c = getchar();
while (c < 48 || c > 57){if (c == '-') flag = -1; c = getchar();}
while (c >= 48 && c <= 57){out = (out << 3) + (out << 1) + c - 48; c = getchar();}
return out * flag;
}
int n;
int ch[maxn],pre[maxn],step[maxn],cnt,last;
int sz[maxn],vis[maxn];
char ss[maxn >> 1];
string s;
void ins(int x){
int p = last,np = ++cnt; step[np] = step[p] + 1; last = np;
while (p && !ch[p][x]) ch[p][x] = np,p = pre[p];
if (!p) pre[np] = 1;
else {
int q = ch[p][x];
if (step[q] == step[p] + 1) pre[np] = q;
else {
int nq = ++cnt; step[nq] = step[p] + 1;
for (int i = 0; i < 26; i++) ch[nq][i] = ch[q][i];
pre[nq] = pre[q]; pre[np] = pre[q] = nq;
while (ch[p][x] == q) ch[p][x] = nq,p = pre[p];
}
}
}
int main(){
cnt = last = 1;
for (int i = 1; i <= n; i++){
last = 1;
scanf("%s",ss); int len = strlen(ss);
s[i] = (string)(ss);
for (int i = 0; i < len; i++) ins(ss[i] - 'a');
}
int u;
for (int i = 1; i <= n; i++){
u = 1;
for (unsigned int j = 0; j < s[i].length(); j++){
u = ch[u][s[i][j] - 'a'];
for (int p = u; p && vis[p] != i; p = pre[p])
sz[p]++,vis[p] = i;
}
}
while (q--){
scanf("%s",ss);
int len = strlen(ss),ans = 0;
u = 1;
for (int i = 0; i < len; i++){
if (!(u = ch[u][ss[i] - 'a'])) break;
if (i == len - 1) ans = sz[u];
}
printf("%d\n",ans);
}
return 0;
}


posted @ 2018-03-10 12:21  Mychael  阅读(149)  评论(0编辑  收藏  举报