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?”
有n个大串和m个询问,每次给出一个字符串s询问在多少个大串中出现过
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
题解:
求单个字符串是多个字符串的子串,当然是广义后缀自动机啦。
最后求的是询问串在所有大串中的总共出现次数,加一个cnt数组表示当前串的总共出现次数,还有一个vis数组表示当前后缀自动机中的节点最后一次是属于哪一个串的,如果不属于这次添加的串,更新vis和cnt即可。
AC代码:
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 4e5+50;
int nxt[MAXN][26],fa[MAXN],len[MAXN];
int vis[MAXN],cnt[MAXN];
int last=1,tot=1;
char s[MAXN];
inline void Insert(int x,int id){
int p=last,np=++tot;
last=np,len[np]=len[p]+1;
for(;p&&!nxt[p][x];p=fa[p]) nxt[p][x]=np;
if(!p) fa[np]=1;
else{
int q = nxt[p][x];
if(len[p]+1==len[q]) fa[np]=q;
else{
int nq = ++tot;
cnt[nq]=cnt[q]; len[nq]=len[p]+1;
memcpy(nxt[nq],nxt[q],sizeof(nxt[q]));
vis[nq]=vis[q];
fa[nq]=fa[q];
fa[q]=fa[np]=nq;
for(;p && nxt[p][x]==q;p=fa[p]) nxt[p][x]=nq;
}
}
for(int p=np;p && vis[p]!=id;p=fa[p]) vis[p]=id,cnt[p]++;
}
int main(){
int n,m; scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%s",s);
last = 1;
int l = strlen(s);
for(int j=0;j<l;j++) Insert(s[j]-'a',i);
}
while(m--){
scanf("%s",s);
int l = strlen(s),rt = 1;
for(int i=0;i<l;i++) rt = nxt[rt][s[i]-'a'];
printf("%d\n",cnt[rt]);
}
return 0;
}