建好trie树
当$dp[j]==1$当且仅当存在$dp[k]=1$且$T[k+1,j]==word[i]$
然后乱搞就行了
1 //minamoto 2 #include<iostream> 3 #include<cstdio> 4 #include<cstring> 5 using namespace std; 6 const int N=2e6+10; 7 int n,m,len;char s[N];bool dp[N]; 8 int ch[205][26],val[205],tot; 9 inline void insert(char *s){ 10 int u=0,l=strlen(s+1); 11 len=max(len,l); 12 for(int i=1;i<=l;++i){ 13 int c=s[i]-'a'; 14 if(!ch[u][c]) ch[u][c]=++tot; 15 u=ch[u][c]; 16 } 17 val[u]=1; 18 } 19 inline bool find(int S,int T){ 20 int u=0; 21 for(int i=S;i<=T;++i){ 22 int c=s[i]-'a'; 23 if(!ch[u][c]) return 0; 24 u=ch[u][c]; 25 } 26 return val[u]; 27 } 28 int main(){ 29 // freopen("testdata.in","r",stdin); 30 scanf("%d%d",&n,&m); 31 for(int i=1;i<=n;++i) 32 scanf("%s",s+1),insert(s); 33 for(int i=1;i<=m;++i){ 34 scanf("%s",s+1); 35 memset(dp,0,sizeof(dp)); 36 int l=strlen(s+1),ans=0;dp[0]=1; 37 for(int j=1;j<=l;++j) 38 for(int k=max(j-len,0);k<=j;++k) 39 if(dp[k]&&find(k+1,j)){dp[j]=1,ans=j;break;} 40 printf("%d ",ans); 41 } 42 return 0; 43 }