# BZOJ2780:[SPOJ8093]Sevenk Love Oimaster(广义SAM)

## Description

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?"

## Input

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

## Output

For each question, output the answer in one line.

3 3
abcabcabc
aaa
aafe
abc
a
ca

1
3
1

## Code

 1 #include<iostream>
2 #include<cstring>
3 #include<cstdio>
4 #define N (201000)
5 using namespace std;
6
7 int n,m,l[N],r[N];
8 char s[N<<2],t[N<<1];
9
10 struct SAM
11 {
12     int son[N][28],fa[N],step[N],size[N],vis[N];
13     int p,q,np,nq,last,cnt;
14     SAM(){last=cnt=1;}
15
16     void Insert(int x)
17     {
18         p=last; np=last=++cnt; step[np]=step[p]+1;
19         while (p && !son[p][x]) son[p][x]=np, p=fa[p];
20         if (!p) fa[np]=1;
21         else
22         {
23             q=son[p][x];
24             if (step[q]==step[p]+1) fa[np]=q;
25             else
26             {
27                 nq=++cnt; step[nq]=step[p]+1;
28                 memcpy(son[nq],son[q],sizeof(son[q]));
29                 fa[nq]=fa[q]; fa[q]=fa[np]=nq;
30                 while (son[p][x]==q) son[p][x]=nq,p=fa[p];
31             }
32         }
33     }
34     void Calc()
35     {
36         for (int i=1; i<=n; ++i)
37         {
38             int now=1;
39             for (int j=l[i]; j<r[i]; ++j)
40             {
41                 now=son[now][s[j]-'a'];
42                 int t=now;
43                 while (t && vis[t]!=i) vis[t]=i,++size[t],t=fa[t];
44             }
45         }
46     }
47     void Find(char s[])
48     {
49         int now=1;
50         for (int j=0,l=strlen(s); j<l; ++j)
51             now=son[now][s[j]-'a'];
52         printf("%d\n",size[now]);
53     }
54 }SAM;
55
56 int main()
57 {
58     scanf("%d%d",&n,&m);
59     for (int i=1; i<=n; ++i)
60     {
61         scanf("%s",s+r[i-1]); int len=strlen(s+r[i-1]);
62         l[i]=r[i-1], r[i]=l[i]+len;
63     }
64     for (int i=1; i<=n; ++i,SAM.last=1)
65         for (int j=l[i]; j<r[i]; ++j)
66             SAM.Insert(s[j]-'a');
67     SAM.Calc();
68     for (int i=1; i<=m; ++i)
69         scanf("%s",t),SAM.Find(t);
70 }
posted @ 2018-11-25 18:48  Refun  阅读(226)  评论(0编辑  收藏  举报