zoukankan      html  css  js  c++  java
  • [洛谷P3808]【模板】AC自动机(简单版)

    题目大意:给定n个模式串和1个文本串,求有多少个模式串在文本串里出现过。

    题解:AC自动机

    卡点:

    C++ Code:

    #include <cstdio>
    #include <queue>
    #include <cstring>
    #define maxn 1000010
    using namespace std;
    int n;
    char s[maxn];
    int nxt[maxn][26], fail[maxn], cnt[maxn], tot;
    int root = 0;
    queue<int> q;
    void add(char *s) {
        int now = root, len = strlen(s);
        for (int i = 0; i < len; i++) {
            if (nxt[now][s[i] - 'a']) now = nxt[now][s[i] - 'a'];
            else now = nxt[now][s[i] - 'a'] = ++tot;
        }
        cnt[now]++;
    }
    void build() {
        for (int i = 0; i < 26; i++) 
            if (nxt[root][i]) fail[nxt[root][i]] = root, q.push(nxt[root][i]);
        while (!q.empty()) {
            int x = q.front(); q.pop();
            for (int i = 0; i < 26; i++) {
                if (nxt[x][i]) fail[nxt[x][i]] = nxt[fail[x]][i], q.push(nxt[x][i]);
                else nxt[x][i] = nxt[fail[x]][i];
            }
        }
    }
    int ask(char *s) {
        int now = root, ans = 0, len = strlen(s);
        for (int i = 0; i < len; i++) {
            now = nxt[now][s[i] - 'a'];
            for (int j = now; j && ~cnt[j]; j = fail[j]) ans += cnt[j], cnt[j] = -1;
        }
        return ans;
    } 
    int main() {
        scanf("%d", &n);
        for (int i = 0; i < n; i++) {
            scanf("%s", s);
            add(s);
        }
        build();
        scanf("%s", s);
        printf("%d
    ", ask(s));
        return 0;
    }
    

      

  • 相关阅读:
    JavaOOP对象和封装
    使用socket实现文件复制
    多线程模拟银行取款
    初入多线程示例展示--Runner
    初步学习多线程3
    初步学习多线程2
    初步线程学习1
    守护线程_setDaemon()
    多线程_yield()和sleep()方法比较
    java_多线程_优先级
  • 原文地址:https://www.cnblogs.com/Memory-of-winter/p/9379427.html
Copyright © 2011-2022 走看看