topic
ideas
no aftereffect
Obviously, no matter how a certain prefix is understood, if it can be understood, then the previous decision is equivalent to the latter decision
So this question can be DP
DP equation
Let $dp[i]$ denote whether the prefix i can be understood
Then, obviously the state transition equation is:
$dp[i]=dp[i]||dp[j];;(s[j+1...i]\in D)$
That is to say, now our problem is transformed into: find all the words that can be matched by the i-th forward number
Because the direction and way of counting forward is unique, we think of a string data structure: $Trie$
$Trie$
A very common idea is to insert all words into $trie$, and then use this forward substring to match words
But there is a problem with this: we are matching from a certain deep position of $trie$ to the root, and there may be multiple such start nodes
The root cause of this problem is that we use a suffix to match words, but our $trie$ is saved as a prefix
So, we just need to change the way $trie$ is saved from prefix to suffix
We reverse all words and insert them into $trie$
When looking for $dp[i]$, start from $s[i]$ and move forward, $trie$ starts from the root node, goes down, and goes to the end of a word (in fact, it is the beginning of the word after the reverse) , use this position to update $dp[i]$
Total time efficiency upper limit:
$O\left(m\left(10strlen(s)+O\left(Trie\right)\right)\right)=O\left(2\ast10^8\right)$
But generally it can't reach so much. The last point of my code is 272ms, which is still very stable.
It's really not possible, give oxygen to the evaluation machine [fog]
Code:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
struct node{//trie节点
int num,son[27];
node(){num=0;memset(son,0,sizeof(son));}
}x[210];
int n,m,dp[1000010],cnt;char a[1000010];
void add(char s[20]){//插入单词
int len=strlen(s),cur=0,i;
for(i=len-1;i>=0;i--){
if(!x[cur].son[s[i]-'a']) x[cur].son[s[i]-'a']=++cnt;
cur=x[cur].son[s[i]-'a'];
}
x[cur].num++;
}
void check(char s[],int pos){
int cur=0,i,flag=0;
for(i=pos-1;i>=0;i--){
if(!x[cur].son[s[i]-'a']) break;
cur=x[cur].son[s[i]-'a'];if(x[cur].num&&dp[i]) flag=1;
}
dp[pos]=flag;
}
int main(){
scanf("%d%d",&n,&m);int i,len,l,j,ans;char s[20];
for(i=1;i<=n;i++) scanf("%s",s),add(s);
for(l=1;l<=m;l++){
scanf("%s",a);memset(dp,0,sizeof(dp));
dp[0]=1;len=strlen(a);ans=0;
for(i=1;i<=len;i++){
check(a,i);
if(dp[i]) ans=max(i,ans);
}
printf("%d\n",ans);
}
}