洛谷P3796

题目链接 

题意:有n个由小写字母组成的模式串以及一个文本串T。每个模式串可能会在文本串中出现多次。哪些模式串在文本串T中出现的次数最多。

题解:ac自动机模板加强版,开一个数组单独记录各个字符串出现的次数,找出最多的即可。(数组一定要初始化!!不然会mle!血的教训,找了半天原因,结果是初始化放进函数忘记调用了_''

 1 #include
 2 using namespace std;
 3 
 4 const int maxn=3e5+10;
 5 string s[maxn];
 6 int num[maxn],ch[maxn][26],fail[maxn],ans[maxn];
 7 int sum,n,tot;
 8 
 9 void init()
10 {
11     memset(num,0,sizeof(num));
12     memset(ch,0,sizeof(ch));
13     memset(fail,0,sizeof(fail));
14     memset(ans,0,sizeof(ans));
15     tot=0;
16 }
17 
18 void insert(string a,int v){
19     int now=0;
20     for(int i=0;i){
21         int x=a[i]-'a';
22         if(!ch[now][x]) ch[now][x]=++tot;
23         now=ch[now][x];
24     }
25     num[now]=v;
26 }
27 
28 void getfail(){
29     queue<int>q;
30     for(int i=0;i<26;i++){
31         if(ch[0][i]){
32             q.push(ch[0][i]);
33             fail[ch[0][i]]=0;
34         }
35     }
36     while(!q.empty()){
37         int u=q.front();q.pop();
38         for(int i=0;i<26;i++){
39             int v=ch[u][i];
40             if(!v) ch[u][i]=ch[fail[u]][i];
41             else {
42                 fail[v]=ch[fail[u]][i];
43                 q.push(v);
44             }
45         }
46     }
47 }
48 
49 void query(string a){
50     int now=0;
51     for(int i=0;i){
52         int p=a[i]-'a';
53         now=ch[now][p];
54         for(int j=now;j;j=fail[j])
55             ans[num[j]]++;
56     }
57 }
58 
59 int main()
60 {
61     while(cin>>n&&n){
62         init();         //一定初始化!!
63         for(int i=1;i<=n;i++){
64             cin>>s[i];
65             insert(s[i],i);
66         }
67         getfail();
68         string k;
69         cin>>k;
70         query(k);
71         sum=0;
72         for(int i=1;i<=n;i++)
73             if(ans[i]>sum) sum=ans[i];
74         cout<endl;
75         for(int i=1;i<=n;i++)
76             if(ans[i]==sum) cout<endl;
77     }
78     return 0;
79 }

你可能感兴趣的:(洛谷P3796)