• P3808 【模板】AC自动机(简单版)


    P3808 【模板】AC自动机(简单版)

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

     
    分析:

      建立AC自动机,然后在文本串扫一遍,统计每个串出现的次数。

     

    代码:

    换了种写法

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    
    const int N = 500100;
    char str[N << 1], s[110];
    int ch[N][26], fail[N], val[N], last[N], q[N], L, R, Index;
    
    void Insert(char *s) {
        int len = strlen(s), u = 0;
        for (int i=0; i<len; ++i) {
            int c = s[i] - 'a';
            if (!ch[u][c]) ch[u][c] = ++Index;
            u = ch[u][c];
        }
        val[u] ++;
    }
    void build() {
        L = 1;R = 0;
        fail[0] = 0;
        for (int c=0; c<26; ++c) {
            int u = ch[0][c];
            if (u) fail[u] = 0, q[++R] = u, last[u] = 0;
        }
        while (L <= R) {
            int u = q[L++];
            for (int c=0; c<26; ++c) {
                int v = ch[u][c];
                if (!v) ch[u][c] = ch[fail[u]][c];
                else {
                    q[++R] = v;
                    fail[v] = ch[fail[u]][c];
                    last[v] = val[fail[v]] ? fail[v] : last[fail[v]];
                }
            }
        }
    }
    
    int find(char *s) {
        int Ans = 0, u = 0, len = strlen(s);
        for (int i=0; i<len; ++i) {
            int c = s[i] - 'a';
            u = ch[u][c];
            if (val[u]) Ans += val[u], val[u] = 0;
            int p = u;
            while (last[p]) {
                p = last[p];
                if (val[p]) Ans += val[p], val[p] = 0;
            }
        }
        return Ans;
    }
    
    int main () {
        int n;
        scanf("%d", &n);
        while (n--) {
            scanf("%s", s);
            Insert(s);
        }
        build();
        scanf("%s",str);
        printf("%d
    ",find(str));
        return 0;
    }
    View Code
     
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    
    const int N = 500100;
    char str[N << 1], s[110];
    int ch[N][26], fail[N], val[N], last[N], q[N], L, R, Index;
    
    void Insert(char *s) {
        int len = strlen(s), u = 0;
        for (int i=0; i<len; ++i) {
            int c = s[i] - 'a';
            if (!ch[u][c]) ch[u][c] = ++Index;
            u = ch[u][c];
        }
        val[u] ++;
    }
    void build() {
        L = 1;R = 0;
        fail[0] = 0;
        for (int c=0; c<26; ++c) {
            int u = ch[0][c];
            if (u) fail[u] = 0, q[++R] = u, last[u] = 0;
        }
        while (L <= R) {
            int u = q[L++];
            for (int c=0; c<26; ++c) {
                int v = ch[u][c];
                if (!v) {
                    ch[u][c] = ch[fail[u]][c];
                    continue;
                }
                q[++R] = v;
                int p = fail[u];
                while (p && !ch[p][c]) p = fail[p];
                fail[v] = ch[p][c];
                last[v] = val[fail[v]] ? fail[v] : last[fail[v]];
            }
        }
    }
    
    int find(char *s) {
        int Ans = 0, u = 0, len = strlen(s);
        for (int i=0; i<len; ++i) {
            int c = s[i] - 'a';
            u = ch[u][c];
            if (val[u]) Ans += val[u], val[u] = 0;
            int p = u;
            while (last[p]) {
                p = last[p];
                if (val[p]) Ans += val[p], val[p] = 0;
            }
        }
        return Ans;
    }
    
    int main () {
        int n;
        scanf("%d", &n);
        while (n--) {
            scanf("%s", s);
            Insert(s);
        }
        build();
        scanf("%s",str);
        printf("%d
    ",find(str));
        return 0;
    }
    View Code
  • 相关阅读:
    多窗体
    滚动条
    个人信息调查
    登录页面
    蓝桥杯——放麦子
    java的BigDecimal
    蓝桥杯——判定字符的位置。
    输出日历
    蓝桥杯---简单的计算器
    蓝桥杯--Quadratic Equation
  • 原文地址:https://www.cnblogs.com/mjtcn/p/9356029.html
Copyright © 2020-2023  润新知