Dominating Patterns
题意:给n个短串1个长串,问这个长串中出现次数最多的短串,并输出
学习了lrj不用指针的写法
需要注意的是模板串可能有重复,用map搞一下
1 #include <bits/stdc++.h> 2 using namespace std; 3 #define CLR(m,a) memset(m,a,sizeof(m)) 4 #define LL long long 5 const int maxnode=11000; 6 const int sigma=26; 7 const int maxn=160; 8 map<string,int> mp; 9 struct AC 10 { 11 int ch[maxnode][sigma]; 12 int f[maxnode],val[maxnode],last[maxnode]; 13 int sz; 14 int cnt[maxn]; // 15 16 void init() 17 { 18 CLR(ch[0],0); 19 CLR(cnt,0); 20 sz=1; 21 } 22 int idx(char c) {return c-'a';} 23 void inser(char *s,int v) 24 { 25 int u=0,n=strlen(s); 26 for(int i=0;i<n;i++){ 27 int c=idx(s[i]); 28 if(!ch[u][c]){ 29 CLR(ch[sz],0); 30 val[sz]=0; 31 ch[u][c]=sz++; 32 } 33 u=ch[u][c]; 34 } 35 val[u]=v; 36 } 37 void print(int u) 38 { 39 if(u){ 40 cnt[val[u]]++; 41 print(last[u]); 42 } 43 } 44 void fin(char *s) 45 { 46 int n=strlen(s); 47 int u=0; 48 for(int i=0;i<n;i++){ 49 int c=idx(s[i]); 50 while(u&&!ch[u][c]) u=f[u]; 51 u=ch[u][c]; 52 if(val[u]) print(u); 53 else if(last[u]) print(last[u]); 54 } 55 } 56 void getfail() 57 { 58 queue<int> q; 59 f[0]=0; 60 for(int c=0;c<sigma;c++){ 61 int u=ch[0][c]; 62 if(u){ 63 f[u]=0; 64 q.push(u); 65 last[u]=0; 66 } 67 } 68 while(!q.empty()){ 69 int r=q.front(); 70 q.pop(); 71 for(int c=0;c<sigma;c++){ 72 int u=ch[r][c]; 73 if(!u) continue; 74 q.push(u); 75 int v=f[r]; 76 while(v&&!ch[v][c]) v=f[v]; 77 f[u]=ch[v][c]; 78 last[u]=val[f[u]]?f[u]:last[f[u]]; 79 } 80 } 81 } 82 }; 83 AC ac; 84 char s[1000010],p[155][80]; 85 int n; 86 int main() 87 { 88 while(scanf("%d",&n)&&n){ 89 ac.init(); 90 mp.clear(); 91 for(int i=1;i<=n;i++){ 92 scanf("%s",p[i]); 93 mp[p[i]]=i; 94 ac.inser(p[i],i); 95 } 96 ac.getfail(); 97 scanf("%s",s); 98 ac.fin(s); 99 int ans=-1; 100 for(int i=1;i<=n;i++) if(ac.cnt[i]>ans) ans=ac.cnt[i]; 101 printf("%d\n",ans); 102 for(int i=1;i<=n;i++) if(ans==ac.cnt[mp[p[i]]]) 103 printf("%s\n",p[i]); 104 } 105 return 0; 106 }