# BZOJ2780: [Spoj]8093 Sevenk Love Oimaster（广义后缀自动机，Parent树，Dfs序）

## 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, s
evenk felt angry and began to check oimaster's online talk with ChuYuXun.    Oimaster talked with Ch
uYuXun 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

## 代码：

  1 #include<cstdio>
2 #include<cstring>
3 #include<algorithm>
4 const int N=200000;
5 const int M=1000000;
6 struct sant{
7     int tranc[26];
8     int len;
9     int pre;
10 }s[N];
11 struct pnt{
12     int hd;
13     int col;
14     int ind;
15     int oud;
16 }p[N];
17 struct ent{
18     int twd;
19     int lst;
20 }e[N];
21 struct qust{
22     int l,r;
23     int ans;
24     int no;
25 }q[N];
26 int siz;
27 int fin;
28 int n,Q;
29 int cnt;
30 int dfn;
31 char tmp[N];
32 int line[N];
33 int lst[N];
34 int phr[N];
35 int col[N];
36 void Insert(int c,int whic)
37 {
38     int nwp,nwq,lsp,lsq;
39     nwp=++siz;
40     p[nwp].col=whic;
41     s[nwp].len=s[fin].len+1;
42     for(lsp=fin;lsp&&!s[lsp].tranc[c];lsp=s[lsp].pre)
43         s[lsp].tranc[c]=nwp;
44     if(!lsp)
45         s[nwp].pre=1;
46     else{
47         lsq=s[lsp].tranc[c];
48         if(s[lsq].len==s[lsp].len+1)
49             s[nwp].pre=lsq;
50         else{
51             nwq=++siz;
52             s[nwq]=s[lsq];
53             s[nwq].len=s[lsp].len+1;
54             s[nwp].pre=s[lsq].pre=nwq;
55             while(s[lsp].tranc[c]==lsq)
56             {
57                 s[lsp].tranc[c]=nwq;
58                 lsp=s[lsp].pre;
59             }
60         }
61     }
62     fin=nwp;
63     return ;
64 }
66 {
67     cnt++;
68     e[cnt].twd=t;
69     e[cnt].lst=p[f].hd;
70     p[f].hd=cnt;
71     return ;
72 }
73 void Dfs(int x)
74 {
75     p[x].ind=++dfn;
76     phr[dfn]=x;
77     col[dfn]=p[x].col;
78     for(int i=p[x].hd;i;i=e[i].lst)
79     {
80         int to=e[i].twd;
81         Dfs(to);
82     }
83     p[x].oud=dfn;
84     return ;
85 }
86 bool cmp(qust x,qust y)
87 {
88     return x.r<y.r;
89 }
90 bool cmq(qust x,qust y)
91 {
92     return x.no<y.no;
93 }
94 int lowbit(int x)
95 {
96     return x&(-x);
97 }
98 void update(int pos,int x)
99 {
100     while(pos&&pos<=siz)
101     {
102         line[pos]+=x;
103         pos+=lowbit(pos);
104     }
105     return ;
106 }
107 int query(int pos)
108 {
109     int ans=0;
110     while(pos)
111     {
112         ans+=line[pos];
113         pos-=lowbit(pos);
114     }
115     return ans;
116 }
117 int main()
118 {
119     fin=++siz;
120     scanf("%d%d",&n,&Q);
121     for(int i=1;i<=n;i++)
122     {
123         scanf("%s",tmp+1);
124         fin=1;
125         int len=strlen(tmp+1);
126         for(int j=1;j<=len;j++)
127             Insert(tmp[j]-'a',i);
128     }
129     for(int i=2;i<=siz;i++)
131     Dfs(1);
132
133     for(int i=1;i<=Q;i++)
134     {
135         scanf("%s",tmp+1);
136         int root=1;
137         int len=strlen(tmp+1);
138         for(int j=1;j<=len;j++)
139             root=s[root].tranc[tmp[j]-'a'];
140         q[i].no=i;
141         if(!root)
142             continue;
143         q[i].l=p[root].ind;
144         q[i].r=p[root].oud;
145     }
146     std::sort(q+1,q+Q+1,cmp);
147     int rr=1;
148     for(int i=1;i<=Q;i++)
149     {
150         while(rr<=q[i].r)
151         {
152             if(!col[rr])
153             {
154                 rr++;
155                 continue;
156             }
157             if(lst[col[rr]])
158                 update(lst[col[rr]],-1);
159             update(rr,1);
160             lst[col[rr]]=rr;
161             rr++;
162         }
163         rr--;
164         if(!q[i].l)
165             continue;
166         q[i].ans=query(q[i].r)-query(q[i].l-1);
167     }
168     std::sort(q+1,q+Q+1,cmq);
169     for(int i=1;i<=Q;i++)
170         printf("%d\n",q[i].ans);
171     return 0;
172 }

posted @ 2018-11-30 19:00  Unstoppable728  阅读(214)  评论(0编辑  收藏  举报