HDU 3065 病毒侵襲持續中(AC自動機裸)

題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=3065

題意:給定n個模式串,一個文本串,判斷每個模式串中在文本串中出現的次數。

思路:AC自動機裸題。

代碼:

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <algorithm>
#include <string>
#include <vector>
#include <map>
#include <queue>
#include <stack>

using namespace std;

#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1
#define ceil(x, y) (((x) + (y) - 1) / (y))

const int SIZE = 55;
const int N = 5e4 + 10;
const int M = 1e3 + 10;
const int INF = 0x7f7f7f7f;
const int MAX_WORD = 2e6 + 10;
const double EPS = 1e-9;
const int MOD = 2015;

int sz;
int ch[N][SIZE];
int val[N];
bool vis[N], ed[N];
int f[N];
char model[M][SIZE];
char txt[MAX_WORD];

int newnode() {
    memset(ch[sz], 0, sizeof(ch[sz]));
    f[sz] = 0;
    val[sz] = 0;
    vis[sz] = false;
    ed[sz] = false;
    return sz++;
}

void init() {
    sz = 0;
    newnode();
}

void insert(char *s) {
    int u = 0;
    for (int i = 0; s[i]; i++) {
        int v = s[i] - 'A';
        if (!ch[u][v])
            ch[u][v] = newnode();
        u = ch[u][v];
    }
    ed[u] = true;
}

void getfail() {
    queue<int> q;
    for (int i = 0; i < SIZE; i++)
        if (ch[0][i])
            q.push(ch[0][i]);

    while (!q.empty()) {
        int r = q.front();
        q.pop();
        for (int i = 0; i < SIZE; i++) {
            int v = ch[r][i];
            if (v) {
                q.push(v);
                int u = f[r];
                while (u && !ch[u][i]) u = f[u];
                f[v] = ch[u][i];
            }
            else ch[r][i] = ch[f[r]][i];
        }
    }
}

void find(char *s) {
    getfail();
    int u = 0;
    for (int i = 0; s[i]; i++) {
        if (s[i] >= 'A' && s[i] <= 'Z') {
            int v = s[i] - 'A';
            u = ch[u][v];
            if (ed[u])
                val[u]++;
        }
        else u = 0;
    }
}

int main() {    
    int n;
    while (scanf("%d", &n) != EOF) {
        init();
        for (int i = 0; i < n; i++) {
            scanf("%s", model[i]);
            insert(model[i]);
        }
        scanf("%s", txt);
        find(txt);

        for (int i = 0; i < n; i++) {
            int u = 0;
            for (int j = 0; model[i][j]; j++) {
                int v = model[i][j] - 'A';
                u = ch[u][v];
            }
            if (val[u])
                printf("%s: %d\n", model[i], val[u]);
        }
    }
    return 0;
}
發佈了104 篇原創文章 · 獲贊 6 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章