UVALive - 4670 Dominating Patterns AC 自动机

input

n 1<=n<=150

word1

word2

...

wordn

1<=len(wirdi)<=70

s 1<=len(s)<=1000000

output

最多出现次数

出现最多的串,按输入顺序输出,可能出现相同串,也要输出

做法:用一个end数组记下每个串结尾的字符的下标,对应val为1,每次找到就将val++,然后找到最大的val,输出最大val对应的字符串

  1 #include <cstdio>
  2 #include <queue>
  3 #include <cstring>
  4 #include <iostream>
  5 #include <cstdlib>
  6 #include <algorithm>
  7 #include <vector>
  8 #include <map>
  9 #include <set>
 10 #include <ctime>
 11 #include <cmath>
 12 #include <cctype>
 13 #define MAX 100000
 14 #define LL long long
 15 int cas=1,T,n,sz,maxt,last[160*80],f[160*80],ch[160*80][26],val[160*80],end[160];
 16 char s[MAX*10+10],word[160][80];
 17 int idx(char&c) {return c-'a';}
 18 void inittrie()
 19 {
 20     memset(ch[0],0,sizeof(ch[0]));
 21     sz=1;
 22     val[0]=0;
 23 }
 24 int insert(char*s)
 25 {
 26     int u=0;
 27     for(;*s;s++)
 28     {
 29         int c=idx(*s);
 30         if(!ch[u][c])
 31         {
 32             memset(ch[sz],0,sizeof(ch[0]));
 33             val[sz]=0;
 34             ch[u][c]=sz++;
 35         }
 36         u=ch[u][c];
 37     }
 38     val[u]=1;
 39     return u;
 40 }
 41 void getFail()
 42 {
 43     std::queue<int>q;
 44     f[0]=0;
 45     for(int c=0;c<26;c++)
 46     {
 47         int u=ch[0][c];
 48         if(u) { f[u]=0;q.push(u);last[u]=0; }
 49     }
 50     while(!q.empty())
 51     {
 52         int r=q.front();q.pop();
 53         for(int c=0;c<26;c++)
 54         {
 55             int u=ch[r][c];
 56             if(!u){ ch[r][c]=ch[f[r]][c];continue; }
 57             q.push(u);
 58             int v=f[r];
 59             while(v&&!ch[v][c]) v=f[v];
 60             f[u]=ch[v][c];
 61             last[u]=val[f[u]]?f[u]:last[f[u]];
 62         }
 63     }
 64 }
 65 void print(int j)
 66 {
 67     if(j)
 68     {
 69         if(val[j]) val[j]++;
 70         print(last[j]);
 71     }
 72 }
 73 void find(char*s)
 74 {
 75     int n=strlen(s);
 76     int j=0;
 77     for(int i=0;i<n;i++)
 78     {
 79         int c=idx(s[i]);
 80         j=ch[j][c];
 81         //printf("val[%d]=%d\n",j,val[j]);
 82         //if(val[j]) val[j]++;
 83         //else if(last[j]) val[last[j]]++;
 84         if(val[j]) print(j);
 85         else if(last[j]) print(last[j]);
 86     }
 87 }
 88 int main()
 89 {
 90     //freopen("/home/user/桌面/in","r",stdin);
 91     //scanf("%d\n",&T);
 92     while(scanf("%d",&n)==1&&n)
 93     {
 94         inittrie();
 95         for(int i=0;i<n;i++)
 96         {
 97             scanf("%s",word[i]);
 98             end[i]=insert(word[i]);
 99         }
100         maxt=-1;
101 //        for(int i=0;i<n;i++) printf("%d %d %s\n",end[i],val[end[i]],word[i]);
102         getFail();
103         scanf("%s",s);
104         find(s);
105         for(int i=0;i<n;i++) maxt=std::max(maxt,val[end[i]]);
106         printf("%d\n",maxt-1);
107         for(int i=0;i<n;i++) if(val[end[i]]==maxt) puts(word[i]);
108     }
109     //printf("time=%.3lf",(double)clock()/CLOCKS_PER_SEC);
110     return 0;
111 }
View Code

 

posted @ 2015-12-03 18:38  cdongyang  阅读(183)  评论(0编辑  收藏  举报