AC自动机 板子

在Trie上做KMP

https://www.luogu.org/problemnew/show/3808

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#include<cstdio>
#include<queue>
#include<iostream>
#define FOR(i,s,t) for(register int i=s;i<=t;++i)
using std::cin;
const int N=4000011;
char s[N];
int tot,n,ans;
namespace AC_automaton{
    struct Tire{
        int cnt,fail;
        int to[27];
    }tr[N];
    inline void build_tire(){
        int u=0;
        for(register int i=0;s[i]!='\0';++i){
            if(!tr[u].to[s[i]-'a'])
                tr[u].to[s[i]-'a']=++tot;
            u=tr[u].to[s[i]-'a'];
        }
        ++tr[u].cnt;
    }
    inline void build_automaton(){     
        int v,u;
        std::queue<int>q;
        FOR(i,0,25)
            if((v=tr[0].to[i]))
                q.push(v);
        int now;
        while(!q.empty()){
            now=q.front();q.pop();
            FOR(i,0,25){
                v=tr[now].to[i];
                u=tr[now].fail;
                if(v){
                    tr[v].fail=tr[u].to[i];
                    q.push(v);
                }
                else
                    tr[now].to[i]=tr[u].to[i];
            }
        }
    }
    inline void match(){
        int now=0,tmp;
        for(register int i=0;s[i]!='\0';++i){
            now=tr[now].to[s[i]-'a'];
            tmp=now;
            while(tmp&&tr[tmp].cnt!=-1){
                ans+=tr[tmp].cnt;
                tr[tmp].cnt=-1;
                tmp=tr[tmp].fail;
            }
        }
    }
}
using namespace AC_automaton;
int main(){
    scanf("%d\n",&n);
    while(n--){
        scanf("%s",s);
        build_tire();
    }
    tr[0].fail=0;
    build_automaton(); 
    scanf("%s",s);
    match();
    printf("%d\n",ans);
    return 0;
}

  

https://www.luogu.org/problemnew/show/3796

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#include<cstdio>
#include<queue>
#define FOR(i,s,t) for(register int i=s;i<=t;++i)
const int N=1000011;
std::queue<int>q;
namespace AC_automaton{
    int ans[155];
    char s[233][233];
    char A[N];
    struct Tire{
        int fail;
        int to[26];
        int pos;
        inline void init(){
            fail=pos=0;
            FOR(i,0,25)to[i]=0;
        }
    }tr[N];
    int tot;
    inline void insert(char *s,int pos){
        int u=0,v;
        for(register int i=0;s[i]!='\0';++i){
            if(!tr[u].to[s[i]-'a'])
                tr[tr[u].to[s[i]-'a']=++tot].init();       
            u=tr[u].to[s[i]-'a'];
        }
        tr[u].pos=pos;
    }
    inline void build_fail(){
        int u,v,now;
        FOR(i,0,25)
            if((u=tr[0].to[i])){
                tr[u].fail=0;
                q.push(u);
            }
        while(!q.empty()){
            now=q.front();q.pop();
            FOR(i,0,25){
                v=tr[now].to[i];
                u=tr[now].fail;
                if(v){
                    tr[v].fail=tr[u].to[i];
                    q.push(v);
                }
                else
                    tr[now].to[i]=tr[u].to[i];
            }
        }
    }
    inline void match(char *s){
        int now=0,tmp;
        for(register int i=0;s[i]!='\0';++i){
            now=tr[now].to[s[i]-'a'];
            tmp=now;
            while(tmp){
                ++ans[tr[tmp].pos];
                tmp=tr[tmp].fail;
            }
        }
    }
}
using namespace AC_automaton;
int n,mx;
int main(){
    while(~scanf("%d",&n)&&n){
        FOR(i,0,n)
            ans[i]=0;
        tot=0;
        tr[0].fail=0;
        tr[0].init();
        FOR(i,1,n){
            scanf("%s",s[i]);
            insert(s[i],i);
        }
        build_fail();
        scanf("%s",A);
        match(A);
        ans[0]=0;
        mx=1;
        FOR(i,1,n)
            if(ans[mx]<ans[i])
                mx=i;
        printf("%d\n",ans[mx]);
        FOR(i,1,n)
            if(ans[mx]==ans[i])
                printf("%s\n",s[i]);
    }
    return 0;
}

  

posted @   Stump  阅读(190)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示