hdu3065
题意:给出n个病毒串(模式串),再给出一个待匹配串,问每种模式串在其中出现了几次,0次不输出
也是将AC自动机的模板稍微修改了一下,由于每个模式串都不同,所以直接用cnt数组记录结点代表的模式串的标号,在匹配串时计数就可以了
1 #include<stdio.h> 2 #include<string.h> 3 #include<queue> 4 using namespace std; 5 const int maxm=1010*55; 6 7 char s[2000000+50],word[1010][55]; 8 int c; 9 int vis[1010]; 10 int nxt[maxm][128-30],cnt[maxm],fail[maxm],size; 11 12 int newnode(){ 13 memset(nxt[size],0,sizeof(nxt[size])); 14 fail[size]=cnt[size]=0; 15 return size++; 16 } 17 18 void insert(char s[],int k){ 19 int i,p=0; 20 for(i=0;s[i];i++){ 21 int &x=nxt[p][s[i]-30]; 22 p=x?x:x=newnode(); 23 } 24 cnt[p]=k; 25 } 26 27 void makenxt(){ 28 int i; 29 queue<int>q; 30 q.push(0); 31 while(!q.empty()){ 32 int u=q.front(); 33 q.pop(); 34 for(i=0;i<128-30;i++){ 35 int v=nxt[u][i]; 36 if(v==0)nxt[u][i]=nxt[fail[u]][i]; 37 else q.push(v); 38 if(u&&v){ 39 fail[v]=nxt[fail[u]][i]; 40 } 41 } 42 } 43 } 44 45 void query(char s[]){ 46 int d=0; 47 for(int i=0;s[i];i++){ 48 d=nxt[d][s[i]-30]; 49 int tmp=d; 50 while(tmp!=0){ 51 vis[cnt[tmp]]++; 52 tmp=fail[tmp]; 53 } 54 } 55 } 56 57 int main(){ 58 int n; 59 while(scanf("%d",&n)!=EOF){ 60 size=0,newnode(); 61 int i; 62 memset(cnt,0,sizeof(cnt)); 63 memset(vis,0,sizeof(vis)); 64 for(i=1;i<=n;i++){ 65 scanf("%s",word[i]); 66 insert(word[i],i); 67 } 68 makenxt(); 69 scanf("%s",s); 70 query(s); 71 for(i=1;i<=n;i++){ 72 if(vis[i])printf("%s: %d\n",word[i],vis[i]); 73 } 74 } 75 return 0; 76 }
hdu3065
时间: 2024-11-04 19:31:26