题意:
有n(<=10000个模式串(length<=50),现在有一个串(<=1000000)..问其中出现了多少个模式串.
题解:
裸AC自动机....空间限制略恶心..直接用指针会好一些....更新模板...
Program:
#include<iostream> #include<cstring> #include<cstdio> #include<queue> #define ll long long #define MAXNODE 242005 using namespace std; class Ac_Atomation { private: struct node { int son[26],fail,w; }T[MAXNODE]; int num; queue<int> Q; public: void clear() { memset(T,0,sizeof(T)),num=0; } void insert(char *s) { int i,h=0,x,len=strlen(s); for (i=0;i<len;i++) { x=s[i]-'a'; if (!T[h].son[x]) T[h].son[x]=++num; h=T[h].son[x]; } T[h].w++; } void built() { int i,h,x; while (Q.size()) Q.pop(); for (i=0;i<26;i++) if (T[0].son[i]) Q.push(T[0].son[i]); while (Q.size()) { h=Q.front(),Q.pop(); for (i=0;i<26;i++) { for (x=T[h].fail;x && !T[x].son[i];x=T[x].fail); T[T[h].son[i]].fail=T[x].son[i]; if (!T[h].son[i]) T[h].son[i]=T[x].son[i]; else Q.push(T[h].son[i]); } } } int exit(char *s,int n) { int i,h=0,p,x,ans=0,len=strlen(s); char c; for (i=0;i<len;i++) { x=s[i]-'a'; h=T[h].son[x]; for (p=h;p;p=T[p].fail) if (T[p].w) ans+=T[p].w,T[p].w=0; } return ans; } }T; char s[1000005]; int main() { int cases,i,n; scanf("%d",&cases); while (cases--) { T.clear(); scanf("%d",&n); while (n--) scanf("%s",s),T.insert(s); T.built(); scanf("%s",s); printf("%d\n",T.exit(s,n)); } return 0; }