AC自动机+DP
AC自动机NOIP考不考啊。。。
在AC自动机上做个DP。
设状态f[i]表示最远可以匹配到的i,然后在AC自动机上找就行了。
#include <iostream> #include <queue> #include <cstdio> #include <cstring> using namespace std; const int N=1100005; int f[N],len[205]; struct AC { char s[N]; int val[205],tr[205][26],tot,fail[205]; void insert(char *ch) { int l=strlen(ch+1),p=0; for(int i=1;i<=l;i++) { if(!tr[p][ch[i]-'a']) tr[p][ch[i]-'a']=++tot; p=tr[p][ch[i]-'a']; } val[p]=1; len[p]=l; } void getfail() { queue<int>q; for(int i=0;i<26;i++) if(tr[0][i]) q.push(tr[0][i]); while(!q.empty()) { int u=q.front();q.pop(); for(int i=0;i<26;i++) { if(!tr[u][i]) tr[u][i]=tr[fail[u]][i]; else fail[tr[u][i]]=tr[fail[u]][i],q.push(tr[u][i]); } val[u]|=val[fail[u]]; } } void query(char *ch) { int l=strlen(ch+1),p=0; for(int i=1;i<=l;i++) { p=tr[p][ch[i]-'a']; if(val[p]) { int tp=p; while(tp) f[i]|=f[i-len[tp]],tp=fail[tp]; } } } }ac; int n,m; int main() { scanf("%d%d",&n,&m); char ch[N]; for(int i=1;i<=n;i++) { scanf("%s",ch+1); ac.insert(ch); } ac.getfail(); for(int i=1;i<=m;i++) { scanf("%s",ch+1); memset(f,0,sizeof f); f[0]=1; ac.query(ch); int len=strlen(ch+1); for(int j=1;j<=len;j++) if(!f[j]) { printf("%d ",j-1);break; } } return 0; }