题目链接:戳我
刚看到题的时候以为就是一个AC自动机模板,直接往后面匹配就行了。
但是再读读题,发现并不是这样子的,匹配上的字符串不能相交,而且必须相接。直接在AC自动机上匹配,只能保证匹配上。
但是我们可以用DP,以(dp[i])表示前i个数都能够被理解。
这样子(dp[i]|=dp[i-length(k)])其中,k是我们匹配上的字符串。
然后...... 然后还是一个AC自动机模板.......
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#define MAXN 1000010
using namespace std;
int n,m,tot;
int done[MAXN],lenth[MAXN];
char cur[MAXN];
struct Node{int ch[26],fail,end,dep;}t[MAXN<<1];
inline void init(char *s)
{
int len=strlen(s+1),x=0;
for(int i=1;i<=len;i++)
{
if(!t[x].ch[s[i]-'a']) t[x].ch[s[i]-'a']=++tot;
x=t[x].ch[s[i]-'a'];
t[x].dep=i;
}
t[x].end=1;
}
inline void get_fail()
{
queue<int>q;
int x=0;
for(int i=0;i<=25;i++)
if(t[x].ch[i])
t[t[x].ch[i]].fail=0,q.push(t[x].ch[i]);
while(!q.empty())
{
int u=q.front();q.pop();
for(int i=0;i<=25;i++)
{
if(t[u].ch[i]) t[t[u].ch[i]].fail=t[t[u].fail].ch[i],q.push(t[u].ch[i]);
else t[u].ch[i]=t[t[u].fail].ch[i];
}
}
}
inline void query(char *s)
{
int len=strlen(s+1),x=0;
for(int i=1;i<=len;i++)
{
x=t[x].ch[s[i]-'a'];
for(int j=x;j;j=t[j].fail)
if(t[j].end==1&&done[i-t[j].dep]==1)
{
done[i]=1;
lenth[i-t[j].dep]=t[j].dep;
}
}
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("ce.in","r",stdin);
#endif
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%s",cur+1);
init(cur);
}
get_fail();
for(int i=1;i<=m;i++)
{
memset(done,0,sizeof(done));
memset(lenth,0,sizeof(lenth));
scanf("%s",cur+1);
done[0]=1;
query(cur);
int last=0;
for(int j=1,len=strlen(cur+1);j<=len;j++)
if(done[j]) last=max(last,lenth[j]+j);
printf("%d
",last);
}
return 0;
}