hdu2896 AC自动机
MLE无数发。后来换了c++交过了。。。
来个标记数组即可。
#include<stdio.h> #include<string.h> #include<stdlib.h> #include<algorithm> #define maxn 10010 using namespace std; struct actrie { actrie *fail; actrie *next[94]; int flag; int id; void init(){ fail=NULL; memset(next,NULL,sizeof(next)); flag=0; } }*q[60200]; actrie *root; char s[maxn],str[210]; int vis[550]; void insert(char *s,int c) { actrie *p=root,*qq; int i,j,len=strlen(s); for(i=0;i<len;i++) { int id=s[i]-32; if(p->next[id]==NULL) { qq=new actrie; qq->init(); p->next[id]=qq; } p=p->next[id]; } p->flag++; p->id=c+1; } void getfail() { actrie *p,*temp; int i,j; int head,tail; head=tail=0; q[tail++]=root; while(head!=tail) { p=q[head++]; for(i=0;i<94;i++) { if(p->next[i]==NULL) continue; if(p->next[i]!=NULL) { if(p==root) p->next[i]->fail=root; else { temp=p->fail; while(temp!=NULL) { if(temp->next[i]!=NULL) { p->next[i]->fail=temp->next[i]; break; } temp=temp->fail; } if(temp==NULL) p->next[i]->fail=root; } q[tail++]=p->next[i]; } } } } int query(char *s) { int i,len=strlen(s),flag; actrie *p=root,*temp; flag=0; memset(vis,0,sizeof(vis)); for(i=0;i<len;i++) { int id=s[i]-32; while(p->next[id]==NULL&&p!=root) p=p->fail; p=p->next[id]; if(p==NULL) p=root; temp=p; while(temp!=root) { if(temp->flag>0) { vis[temp->id]=1; flag=1; } temp=temp->fail; } } return flag; } int main() { int i,j,t,n,m; while(scanf("%d",&n)!=EOF) { root=new actrie; root->init(); for(i=0;i<n;i++) { scanf("%s",str); insert(str,i); } getfail(); scanf("%d",&m); int ans=0; for(i=0;i<m;i++) { scanf("%s",s); if(query(s)) { ans++; printf("web %d:",i+1); for(j=1;j<=n;j++) if(vis[j]) printf(" %d",j); printf("\n"); } } printf("total: %d\n",ans); } }