最近看了下AC自动机,觉得没有什么卵用。不过还是记录下。
#define MAXTREENODE 400400 struct ACtree { int next[MAXTREENODE][26],times[MAXTREENODE],fail[MAXTREENODE]; int head,treeid; int que[MAXTREENODE]; int qf,qd; int newnode() { memset(next[treeid],-1,sizeof(next[treeid])); times[treeid]=0; fail[treeid]=-1; treeid++; return treeid-1; } void init() { treeid=0; head = newnode(); } void acinsert(char *str) { int len=strlen(str); int tmpid=head; for(int i=0;i<len;i++) { int to=str[i]-'a'; if(next[tmpid][to]==-1) next[tmpid][to] = newnode(); tmpid = next[tmpid][to]; } times[ tmpid ] ++; } void build() { qf=qd=0; for(int i=0;i<26;i++) if(next[head][i] == -1) next[head][i] = head; else { que[qf++] = next[head][i]; fail[ next[head][i] ] = head; } while( qf>qd ) { int cur = que[qd++]; for(int i=0;i<26;i++) { if( next[cur][i] == -1 ) next[cur][i] = next[ fail[cur] ][i]; else { que[qf++] = next[cur][i]; fail[ next[cur][i] ] = next[ fail[cur] ][i]; } } } } int acquery(char * str) { int len=strlen(str); int acsum=0; int nowid=head; for(int i=0;i<len;i++) { int to=str[i]-'a'; nowid = next[nowid][to]; int tmpid=nowid; while(tmpid!=head) { acsum += times[tmpid]; times[ tmpid ] = 0; tmpid = fail[tmpid]; } } return acsum; } };