算是ac自动机的入门题了吧。就是给了最多170个长为最多70的模板串,然后给出一个文本串,让按输入顺序输出所有的文本串匹配点最多的那些串。
因为模板串多个且长度较小,而文本串较长1e6,所
#include <queue> #include <cstdio> #include <cstring> #include <vector> #include <map> #include <iostream> #include <algorithm> using namespace std; typedef long long LL; #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define rep(i,n) for(int (i)=0;(i)<(n);i++) #define Rep(i,n) for(int (i)=1;(i)<=(n);i++) #define rep1(i,x,y) for(int (i)=x;(i)<=y;i++) const int sigmasize = 26; const int N = 71*151; struct Aho_Corasick{ int ch[N][sigmasize]; int val[N],last[N],f[N],cou[N]; int cnt; map<string,int> ms; int idx(char c){return c-'a';} void clear(){ cnt = 1; memset(val,0,sizeof(val)); memset(ch[0],0,sizeof(ch[0])); memset(cou,0,sizeof(cou)); ms.clear(); } void insert(char* s,int v){ int n=strlen(s),u=0; rep(i,n){ int c=idx(s[i]); if(!ch[u][c]){ ch[u][c] = cnt; memset(ch[cnt],0,sizeof(ch[cnt])); cnt++; } u = ch[u][c]; } val[u] = v; ms[string(s)]=v; } void print(int i,int u){ if(u){ // printf("%d is found st position %d\n",val[u],i); cou[val[u]]++; print(i,last[u]); } } void find(char* T){ int n=strlen(T),j=0; rep(i,n){ int c=idx(T[i]); j = ch[j][c]; if(val[j]) print(i,j); else if(last[j]) print(i,last[j]); } } void init(){ queue<int> Q; last[0]=f[0]=0; rep(i,sigmasize){ if(ch[0][i]) { f[ch[0][i]]=last[i]=0; Q.push(ch[0][i]); } } while(!Q.empty()){ int r=Q.front(); Q.pop(); rep(i,sigmasize){ int u=ch[r][i]; if(!u){ch[r][i]=ch[f[r]][i]; continue;} f[u]=ch[f[r]][i]; last[u] = val[f[u]] ? f[u]:last[f[u]]; Q.push(u); } } } }; int n,Q; char str[180][100],src[1010101]; int main() { Aho_Corasick ac; while(scanf("%d",&n)==1 && n){ ac.clear(); Rep(i,n){ scanf("%s",str[i]); ac.insert(str[i],i); } ac.init(); scanf("%s",src); ac.find(src); int best = 0; Rep(i,n) if(ac.cou[i]>best) { best=ac.cou[i]; } printf("%d\n",best); Rep(i,n){ if(ac.cou[ac.ms[string(str[i])]] == best) printf("%s\n",str[i]); } } return 0; }
即可。