枚举每个文章里已经在Trie中被标记为可能是分割处的字符,然后再从此处跑Trie,继续向后标记。由于单词数很少,因此复杂度可以接受,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; }
时间: 2024-10-15 08:40:05