首先用广义SAM求出每个询问串以每个位置结尾的最长匹配长度,然后二分答案然后dp即可。注意到转移区间显然单调所以单调队列即可。
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<queue>
#define SIG 2
#define N 1200000
#define debug(x) cerr<<#x<<"="<<x
#define sp <<" "
#define ln <<endl
using namespace std;
struct SAM{
int ch[N<<1][2],fa[N],val[N],node_cnt;
SAM() { node_cnt=1; }
inline int new_sam_node(int v,int x=0)
{ return x=++node_cnt,val[x]=v,x; }
inline int extend(int las,int w)
{
int p=las,np=new_sam_node(val[p]+1);
while(p&&!ch[p][w]) ch[p][w]=np,p=fa[p];
if(!p) fa[np]=1;
else{
int q=ch[p][w],v=val[p]+1;
if(val[q]==v) fa[np]=q;
else{
int nq=new_sam_node(v);
fa[nq]=fa[q],fa[q]=fa[np]=nq;
memcpy(ch[nq],ch[q],sizeof(ch[q]));
while(p&&ch[p][w]==q) ch[p][w]=nq,p=fa[p];
}
}
return np;
}
inline int run(char *s,int n,int *p)
{
for(int i=1,x=1,l=0;i<=n;p[i]=i-l+1,i++)
{
int c=s[i]-'0';
while(x&&!ch[x][c]) l=val[x=fa[x]];
if(x) x=ch[x][c],l++;else x=1;
}
return 0;
}
}t;
struct Trie{
queue<int> q;int ch[N][2],las[N],node_cnt;
Trie() { node_cnt=1; }
inline int insert(char *s)
{
for(int i=1,n=(int)strlen(s+1),x=1,c;i<=n;i++)
{
if(!ch[x][c=s[i]-'0'])
ch[x][c]=++node_cnt;
x=ch[x][c];
}
return 0;
}
inline int build_sam(SAM &t)
{
while(!q.empty()) q.pop();
q.push(1),las[1]=1;
while(!q.empty())
{
int x=q.front();q.pop();
for(int i=0,c;i<SIG;i++)
if(c=ch[x][i]) las[c]=t.extend(las[x],i),q.push(c);
}
return 0;
}
}tr;
int dp[N],p[N],q[N],f[N];char s[N];
inline int check(int L,int n)
{
for(int i=1,fp=1,rp=0,x=0,y=-1;i<=n;f[i]=dp[i]-i,i++)
{
dp[i]=dp[i-1];if(p[i]>i-L+1) continue;
while(y<i-L)
{
y++;
while(fp<=rp&&f[y]>=f[q[rp]]) rp--;
q[++rp]=y;
}
while(x<p[i]-1)
{
if(fp<=rp&&q[fp]==x) fp++;
x++;
}
if(fp<=rp) dp[i]=max(dp[i],i+f[q[fp]]);
}
return 10*dp[n]>=9*n;
}
int main()
{
int n,m;scanf("%d%d",&m,&n);
for(int i=1;i<=n;i++) scanf("%s",s+1),tr.insert(s);
tr.build_sam(t);
for(int i=1,l,L,R,n,mid;i<=m;i++)
{
scanf("%s",s+1),l=(int)strlen(s+1);
t.run(s,l,p),L=1,R=l,mid=(L+R)>>1;
while(L<=R)
{
if(check(mid,l)) L=mid+1;
else R=mid-1;mid=(L+R)>>1;
}
printf("%d\n",R);
}
return 0;
}