hdu 2222 Keywords Search ac自动机
单词会重复,算完顺带清0就行了
#include<cstdio> #include<cstring> #include<queue> using namespace std; const int son_num=26; const int max_node=250010; class ACAutomaton { private: int sz; int trie[max_node][son_num]; int val[max_node]; int fail[max_node]; public: int idx(char c) { return c-'a'; } void init() { sz=0; memset(trie,0,sizeof(trie)); memset(val,0,sizeof(val)); } void insert(char *T,int key) { int u,c,n,i,j; u=0; n=strlen(T); for(i=0;i<n;i++) { c=idx(T[i]); if(!trie[u][c])trie[u][c]=++sz; u=trie[u][c]; } val[u]+=key; } int query(char *T) { int u,c,res,n,i,j; u=0; res=0; n=strlen(T); for(i=0;i<n;i++) { c=idx(T[i]); u=trie[u][c]; if(val[u])print(u,res); } return res; } void print(int u,int &res) { if(val[u]) { res+=val[u]; val[u]=0; print(fail[u],res); } } void getfail() { queue<int> q; int u,c,r,v; fail[0]=0; for(c=0;c<son_num;c++) { u=trie[0][c]; if(u) { fail[u]=0; q.push(u); } } while(!q.empty()) { r=q.front();q.pop(); for(c=0;c<son_num;c++) { u=trie[r][c]; if(!u) { trie[r][c]=trie[fail[r]][c]; continue; } q.push(u); v=fail[r]; while(v&&!trie[v][c])v=fail[v]; fail[u]=trie[v][c]; } } } }ac; char T[1000000+10]; char s[60]; int main() { int t,n; scanf("%d",&t); while(t--) { ac.init(); scanf("%d",&n); while(n--) { scanf("%s",s); ac.insert(s,1); } ac.getfail(); scanf("%s",T); printf("%d\n",ac.query(T)); } }
浙公网安备 33010602011771号