• HDU 3065 病毒侵袭持续中(AC自动机 模板)题解


    题意:给出主串中每个模式串的个数

    思路:毒瘤出题人多组数据没说给的是多组数据。

    板子:

    struct Aho{
        struct state{
            int next[130];
            int fail, cnt;
        }node[maxn];
        int size;
        queue<int> q;
    
        void init(){
            size = 0;
            newtrie();
            while(!q.empty()) q.pop();
        }
    
        int newtrie(){
            memset(node[size].next, 0, sizeof(node[size].next));
            node[size].cnt = node[size].fail = 0;
            return size++;
        }
    
        void insert(char *s, int id){
            int len = strlen(s);
            int now = 0;
            for(int i = 0; i < len; i++){
                int c = s[i];
                if(node[now].next[c] == 0){
                    node[now].next[c] = newtrie();
                }
                now = node[now].next[c];
            }
            node[now].cnt = id;
        }
    
        void build(){
            node[0].fail = -1;
            q.push(0);
    
            while(!q.empty()){
                int u = q.front();
                q.pop();
                for(int i = 0; i < 130; i++){
                    if(node[u].next[i]){
                        if(u == 0) node[node[u].next[i]].fail = 0;
                        else{
                            int v = node[u].fail;
                            while(v != -1){
                                if(node[v].next[i]){
                                    node[node[u].next[i]].fail = node[v].next[i];
                                    break;
                                }
                                v = node[v].fail;
                            }
                            if(v == -1) node[node[u].next[i]].fail = 0;
                        }
                        q.push(node[u].next[i]);
                    }
                }
            }
        }
    
        void get(int u){ //匹配规则
            while(u){
                if(node[u].cnt) ans[node[u].cnt]++;
                u = node[u].fail;
            }
        }
    
        void match(char *s){
            int ret = 0, now = 0;
            int len = strlen(s);
            for(int i = 0; i < len; i++){
                int c = s[i];
                if(node[now].next[c]){
                    now = node[now].next[c];
                }
                else{
                    int p = node[now].fail;
                    while(p != -1 && node[p].next[c] == 0){
                        p = node[p].fail;
                    }
                    if(p == -1) now = 0;
                    else now = node[p].next[c];
                }
                get(now);    //视情况自己定
            }
        }
    }ac;

    代码:

    #include<set>
    #include<map>
    #include<cmath>
    #include<queue>
    #include<cstdio>
    #include<vector>
    #include<cstring>
    #include <iostream>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    const int maxn = 50000 + 10;
    const int maxM = 2000000 + 10;
    const ull seed = 131;
    const int INF = 0x3f3f3f3f;
    const int MOD = 1e4 + 7;
    
    char s[maxM];
    char b[1001][51];
    int ans[1001];
    struct Aho{
        struct state{
            int next[130];
            int fail, cnt;
        }node[maxn];
        int size;
        queue<int> q;
    
        void init(){
            size = 0;
            newtrie();
            while(!q.empty()) q.pop();
        }
    
        int newtrie(){
            memset(node[size].next, 0, sizeof(node[size].next));
            node[size].cnt = node[size].fail = 0;
            return size++;
        }
    
        void insert(char *s, int id){
            int len = strlen(s);
            int now = 0;
            for(int i = 0; i < len; i++){
                int c = s[i];
                if(node[now].next[c] == 0){
                    node[now].next[c] = newtrie();
                }
                now = node[now].next[c];
            }
            node[now].cnt = id;
        }
    
        void build(){
            node[0].fail = -1;
            q.push(0);
    
            while(!q.empty()){
                int u = q.front();
                q.pop();
                for(int i = 0; i < 130; i++){
                    if(node[u].next[i]){
                        if(u == 0) node[node[u].next[i]].fail = 0;
                        else{
                            int v = node[u].fail;
                            while(v != -1){
                                if(node[v].next[i]){
                                    node[node[u].next[i]].fail = node[v].next[i];
                                    break;
                                }
                                v = node[v].fail;
                            }
                            if(v == -1) node[node[u].next[i]].fail = 0;
                        }
                        q.push(node[u].next[i]);
                    }
                }
            }
        }
    
        void get(int u){ //匹配规则
            while(u){
                if(node[u].cnt) ans[node[u].cnt]++;
                u = node[u].fail;
            }
        }
    
        void match(char *s){
            int ret = 0, now = 0;
            int len = strlen(s);
            for(int i = 0; i < len; i++){
                int c = s[i];
                if(node[now].next[c]){
                    now = node[now].next[c];
                }
                else{
                    int p = node[now].fail;
                    while(p != -1 && node[p].next[c] == 0){
                        p = node[p].fail;
                    }
                    if(p == -1) now = 0;
                    else now = node[p].next[c];
                }
                get(now);
            }
        }
    }ac;
    
    
    int main(){
        int n;
        while(~scanf("%d", &n)){
            ac.init();
            for(int i = 1; i <= n; i++){
                scanf("%s", b[i]);
                ac.insert(b[i], i);
                ans[i] = 0;
            }
            ac.build();
            getchar();
            scanf("%s", s);
            ac.match(s);
            for(int i = 1; i <= n; i++){
                if(ans[i]){
                    printf("%s: %d
    ", b[i], ans[i]);
                }
            }
        }
        return 0;
    }
  • 相关阅读:
    01Game
    面试题
    面试题
    面向对象笔记
    1212作业
    12011作业
    1210作业
    1206作业
    1205作业
    1204作业
  • 原文地址:https://www.cnblogs.com/KirinSB/p/11176665.html
Copyright © 2020-2023  润新知