复习了一下板子。
指针实现占内存比较大,要是卡内存就恶心了……
指针实现:
struct AC { struct trie { trie *nxt[94],*fail; short inc,ct; trie(){for(int i=0;i<94;i++)nxt[i]=NULL;fail=NULL;inc=0;ct=0;} }*root=new trie(); queue<trie*>q;vector<short>al; void insert(char *s,int id) { trie *p=root;int n=strlen(s); for(int i=0;i<n;i++) { if(p->nxt[s[i]-' ']==NULL)p->nxt[s[i]-' ']=new trie(); p=p->nxt[s[i]-' ']; }p->inc=id; } void build() { q.push(root); while(!q.empty()) { trie *p=q.front();q.pop(); for(int i=0;i<94;i++) if(p->nxt[i]) p->nxt[i]->fail=(p==root?p:p->fail->nxt[i]),q.push(p->nxt[i]); else p->nxt[i]=(p==root?p:p->fail->nxt[i]); } } void ask(char *s,int tim) { al.clear();int n=strlen(s);trie *p=root; for(int i=0;i<n;i++) { p=p->nxt[s[i]-' ']; trie *tmp=p; while(tmp!=root&&tmp->ct!=tim) { if(tmp->inc)al.push_back(tmp->inc); tmp->ct=tim;tmp=tmp->fail; } } } }T;
数组实现:
struct AC { int nxt[100000][130],fail[100000],inc[100000],ct[100000]; int cnt=1,root=1; queue<int>q;vector<short>al; void insert(char *s,int id) { int p=root;int n=strlen(s); for(int i=0;i<n;i++) { if(nxt[p][s[i]-' ']==0)nxt[p][s[i]-' ']=++cnt; p=nxt[p][s[i]-' ']; }inc[p]=id; } void build() { q.push(root); while(!q.empty()) { int p=q.front();q.pop(); for(int i=0;i<94;i++) if(nxt[p][i]) fail[nxt[p][i]]=(p==root?p:nxt[fail[p]][i]),q.push(nxt[p][i]); else nxt[p][i]=(p==root?p:nxt[fail[p]][i]); } } void ask(char *s,int tim) { al.clear();int n=strlen(s);int p=root; for(int i=0;i<n;i++) { p=nxt[p][s[i]-' ']; int tmp=p; while(tmp!=root&&ct[tmp]!=tim) { if(inc[tmp])al.push_back(inc[tmp]); ct[tmp]=tim;tmp=fail[tmp]; } } } }T;