Description:
给出n个串和m个串,
分别求出这m个串能被n个串中的串拼出的最长前缀
注意:一定是拼出,串不能重叠!!!
Hint:
(n,m<=20)
$ len_n<=10 ,len_m<=10^6 $
Solution:
一开始看错题了,还有60多分.....
正解直接dp一下就行了
#include<bits/stdc++.h>
using namespace std;
const int mxn=1e7+5;
int f[mxn];
char str[mxn],p[80],vis[mxn];
queue<int > q;
namespace Trie {
int tot,fail[mxn],val[mxn];
int t[mxn][26];
void ins(char *s) {
int len=strlen(s),u=0;
for(int i=0;i<len;++i) {
if(!t[u][s[i]-'a']) t[u][s[i]-'a']=++tot;
u=t[u][s[i]-'a'];
}
val[u]=len;
};
void build() {
for(int i=0;i<26;++i)
if(t[0][i]) fail[t[0][i]]=0,q.push(t[0][i]);
while(!q.empty()) {
int u=q.front(); q.pop();
for(int i=0;i<26;++i) {
if(t[u][i]) fail[t[u][i]]=t[fail[u]][i],q.push(t[u][i]);
else t[u][i]=t[fail[u]][i];
}
}
};
int query(char *s) {
int len=strlen(s),u=0,ans=0,mi=0;
for(int i=0;i<=len;++i) f[i]=0;
f[0]=1;
for(int i=0;i<len;++i) {
u=t[u][s[i]-'a']; vis[i]=0;
for(int v=u;v;v=fail[v])
if(val[v]) {
f[i+1]|=f[i-val[v]+1];
}
}
for(int i=len;i>=0;--i)
if(f[i]) return i;
};
}
using namespace Trie;
int main()
{
int n,m; scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i)
scanf("%s",p),ins(p);
build();
while(m--) {
scanf("%s",str);
printf("%d
",query(str));
}
return 0;
}