Enumerate the characters in each article that have been marked as likely to be split in Trie, and then run Trie from there, continuing to mark them backwards. Because of the small number of words, complexity can be accepted, O (N*m*len).
#include <cstdio> #include <cstring>using namespace Std;int n,m,l;char s[1024*1024+100];int ch[21*11][26]; BOOL Is[21*11],end[1024*1024+100];int sz;void Insert (char s[]) {int U=0,len=strlen (s); for (int i=0;i<len;++i) { int v=s[i]-' a '; if (!ch[u][v]) Ch[u][v]=++sz; U=CH[U][V]; } Is[u]=1;} void work (int x) {int i=x,j=ch[0][s[x]-' a '];while (i<l&&j) { if (is[j]) end[i]=1; ++i; J=ch[j][s[i]-' a '];} } int main () {scanf ("%d%d", &n,&m), for (int i=1;i<=n;++i) {scanf ("%s", s); Insert (s);} for (; m;--m) { scanf ("%s", s); L=strlen (s); memset (end,0,l*sizeof (bool)); Work (0); for (int. i=0;i<l-1;++i) if (End[i]) work (i+1); for (int i=l-1;i>=0;--i) if (End[i]) {printf ("%d\n", i+1); goto out;} Puts ("0"); Out:; } return 0;}
"Trie" bzoj1212 [Hnoi2004]l language