今天是第二天集训。(其实已经是第三天了,只是昨天并没有机会来写总结,现在补上)

  上午大家心情都很愉快,因为老师讲了splay树和ac自动机。

  但到了下午,我们的教练竟然跑出去耍了(excuse me?),害的我们在一些不懂的地方冥思苦想浪费时间,效率极其低下,所以说只做了点模板题,以后这方面的知识还需要多多练习0.0

 

  1.ac自动机

  这东西是kmp的升级版本,由一个模式串升级到了多个模式串,效率依然高。

  只要掌握了kmp,ac自动机一般不会有问题。哦,当然你也必须会trie树,这是自动机的基础

  首先,和kmp一样,构造fail数组,也就是next数组。注意:这个fail数组不止能够跳到自己的最大相同前缀上,还能跳到别的串。

  有了fail数组,就可以匹配了,过程也和kmp类似,只不过加一些处理令得模式串之间可以互相到达

      所以,以上我说的全是废话[滑稽]。

  话不多说,上代码(标准模板)

CODE:   HDU2222

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define N 10005
 4 int tr[N*50][26],ls[N*50],n,tot,f[N*50],val[N*50],ans;
 5 char s[1000005],ch[55];
 6 
 7 void adtr(){
 8     int i=0,x=0;
 9     while(ch[i]){
10         int k=ch[i]-'a';
11         if(!tr[x][k])tr[x][k]=++tot;
12         x=tr[x][k];i++;
13     }
14     val[x]++;
15 }
16 
17 void getfail(){
18     queue<int>q;
19     int u,v,rt;
20     for(int i=0;i<26;i++)if(tr[0][i])q.push(tr[0][i]),f[tr[0][i]]=ls[tr[0][i]]=0;
21     while(!q.empty()){
22         rt=q.front();q.pop();
23         for(int i=0;i<26;i++){
24             int u=tr[rt][i];
25             if(!u){tr[rt][u]=tr[f[rt]][u];continue;}
26             q.push(u);
27             v=f[rt];
28             while(v&&!tr[v][i])v=f[v];
29             f[u]=tr[v][i];
30             if(val[f[u]])ls[u]=f[u];
31             else ls[u]=ls[f[u]];
32         }
33     }
34 }
35 
36 void make(int x){
37     if(!x)return;
38     if(val[x])ans+=val[x],val[x]=0;
39     make(ls[x]);
40 }
41 
42 void ac(){
43     int x=0;
44     for(int i=0;s[i];i++){
45         int k=s[i]-'a';
46         //while(x&&!tr[x][k])x=f[x];
47         /*上一句可以省略的原因是  getfail()函数中的这一句 : 
48         if(!u){tr[rt][u]=tr[f[rt]][u];continue;}
49         已经通过迭代求出了最近的有k的串 */
50         x=tr[x][k];
51         if(val[x])make(x);
52         else if(ls[x])make(ls[x]);
53     }
54 }
55 
56 int main(){
57     int T;cin>>T;
58     while(T--){
59         memset(val,0,sizeof(val));
60         memset(tr,0,sizeof(tr));
61         ans=tot=0;scanf("%d",&n);
62         for(int i=1;i<=n;i++)scanf("%s",ch),adtr();
63         getfail();scanf("%s",s);ac();
64         printf("%d\n",ans);
65     }
66 }
点击查看完整版。。

相关文章:

  • 2022-12-23
  • 2021-05-27
  • 2021-04-21
  • 2021-09-28
  • 2021-06-28
  • 2022-12-23
  • 2021-10-06
  • 2022-02-04
猜你喜欢
  • 2021-10-06
  • 2022-12-23
  • 2021-11-30
  • 2021-07-24
  • 2022-12-23
  • 2021-07-03
  • 2021-07-14
相关资源
相似解决方案