题目链接:病毒侵袭
题解:正常建立ac自动机,然后再匹配的时候,用vis数组标记看串有没有匹配过,统计答案就可以了,这题卡空间特别紧。我用memset初始化足够的空间就mle
好像申请空间,oj并不马上分配,放你真正使用才算你使用了。
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn=1e4*50+100; 4 const int N=500*200+10; 5 char ss[(int)1e4+5]; 6 int num; 7 bool an[(int)505]; 8 struct ac_auto 9 { 10 int nxt[N][128],ed[N],fail[N],rt,cn; 11 bool vis[N]; 12 ac_auto(){} 13 void init(){ 14 cn=0; 15 rt=new_node(); 16 } 17 int new_node() 18 { 19 memset(nxt[cn],-1,sizeof(nxt[cn])); 20 ed[cn]=0;fail[cn]=0; 21 return cn++; 22 } 23 void insert(char *s,int id) 24 { 25 int len=strlen(s); 26 int p=rt; 27 for(int i=0;i<len;i++) 28 { 29 int x=s[i]; 30 if(nxt[p][x]==-1)nxt[p][x]=new_node(); 31 p=nxt[p][x]; 32 } 33 ed[p]=id; 34 } 35 void get_fail() 36 { 37 queue<int>que; 38 que.push(rt); 39 while(!que.empty()) 40 { 41 int s=que.front();que.pop(); 42 for(int i=0;i<128;i++) 43 { 44 if(nxt[s][i]!=-1) 45 { 46 if(s==rt) 47 { 48 fail[nxt[s][i]]=rt; 49 } 50 else 51 { 52 int p=fail[s]; 53 while(p!=-1) 54 { 55 if(nxt[p][i]!=-1) 56 { 57 fail[nxt[s][i]]=nxt[p][i];break; 58 } 59 p=fail[p]; 60 } 61 if(p==-1)fail[nxt[s][i]]=rt; 62 } 63 que.push(nxt[s][i]); 64 } 65 66 } 67 } 68 } 69 void ac_automation(char *s) 70 { 71 int p=rt;num=0; 72 memset(vis,0,sizeof(vis)); 73 memset(an,0,sizeof(an)); 74 int len=strlen(s); 75 for(int i=0;i<len;i++) 76 { 77 int x=s[i]; 78 while(p!=-1&&nxt[p][x]==-1)p=fail[p]; 79 if(p==-1)p=rt; 80 else p=nxt[p][x]; 81 int tmp=p; 82 while(tmp!=rt) 83 { 84 if(!vis[tmp]) 85 { 86 if(ed[tmp]>0)an[ed[tmp]]=1,num++; 87 } 88 else break;vis[tmp]=true; 89 tmp=fail[tmp]; 90 } 91 } 92 } 93 }ac; 94 int main() 95 { 96 ac.init(); 97 int n,m; 98 scanf("%d",&n); 99 for(int i=1;i<=n;i++) 100 { 101 scanf("%s",ss); 102 ac.insert(ss,i); 103 } 104 ac.get_fail(); 105 scanf("%d",&m); 106 int cnt=0; 107 for(int i=1;i<=m;i++) 108 { 109 scanf("%s",ss); 110 ac.ac_automation(ss); 111 if(num) 112 { 113 cnt++; 114 printf("web %d:",i); 115 for(int j=0;j<505;j++) 116 { 117 if(an[j])printf(" %d",j); 118 } 119 printf(" "); 120 } 121 } 122 printf("total: %d ",cnt); 123 }