HDU2896.病毒侵袭中【MLE和PE的原因】【AC自动机模板题】

HDU2896.病毒侵袭中(重点:MLE和PE)

AC自动机


题目飞机票
其他AC自动机练习题目(谢谢kuangbin的题目)
AC自动机题解


网上的题解已经很清楚了,我也不再赘述╰(´︶`)╯

给你几个串还有几个模式串,问每一个模式串的匹配数量和总的匹配数量

一个AC自动机的版题,为什么要发个 Blog 也是为了给大家说一声:

  • 如果你写的PE了,很简单,web后面的输出行末不能有空格,先 for 到倒数第二个,再输出最后一个,打个回车
  • C++看这里:如果你写的是指针版的MLE了(指针确实容易错,稍微不注意就会出莫名其妙的问题),如果你确定是对的,看看你交的是不是C++,不要交G++

其他的我也就不多说了

#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;

const int maxn = 1e4 + 13, maxm = 100, maxLen = 513;
int n, m, da[maxLen];
char s[maxn];
bool used[maxLen];
struct node {
    node *next[maxm];
    node *fail;
    int count;
    void init() {
        count = 0;
        fail = NULL;
        for(int i = 0; i < maxm; i++) next[i] = NULL;
    }
}root;
queue*>Q;
struct Aho_Corasick_Automation {
    node *root;
    int tot, ans;
    void init() {
        root = new node;
        root->init();
        ans = 0; tot = 0;
    }
    void insert(char *st) {
        node *p = root;
        for(int i = 0; st[i]; i++) {
            int pos = st[i] - ' ';
            if(!p->next[pos]) {
                p->next[pos] = new node;
                p->next[pos]->init();
            }
            p = p->next[pos];
        }
        p->count = ++tot;
    }
    void getFail() {
        node *p, *fa, *son;
        Q.push(root);
        while(!Q.empty()) {
            fa = Q.front(); Q.pop();
            for(int i = 0; i < maxm; i++) {
                son = fa->next[i];
                if(!son) continue;
                if(fa == root) son->fail = root;
                else {
                    p = fa->fail;
                    while(p != root && !p->next[i]) p = p->fail;
                    p = p->next[i];
                    if(!p) son->fail = root;
                    else son->fail = p;
                }
                Q.push(son);
            }
        }
    }
    void find(int ord, char *st) {
        int size = 0;
        memset(used, 0, sizeof(used));
        node *p, *temp;
        p = root;
        for(int i = 0; st[i]; i++) {
            int pos = st[i] - ' ';
            while(p != root && !p->next[pos]) p = p->fail;
            p = p->next[pos];
            if(!p) p = root;
            temp = p;
            while(temp != root) {
                if(temp->count && !used[temp->count]) {
                    da[++size] = temp->count;
                    used[temp->count] = true;
                    temp = temp->fail;
                }
                else break;
            }
        }
        if(size) ans++;
        else return;
        sort(da + 1, da + size + 1);
        printf("web %d: ", ord);
        for(int i = 1; i < size; i++) printf("%d ", da[i]); printf("%d\n", da[size]);
    }
    int getAns() {return ans;}
}AC;

int main() {
    AC.init();
    scanf("%d", &n);
    for(int i = 1; i <= n; i++) {
        scanf("%s", s);
        AC.insert(s);
    }
    AC.getFail();
    scanf("%d", &m);
    for(int i = 1; i <= m; i++) {
        scanf("%s", s);
        AC.find(i, s);
    }
    printf("total: %d\n", AC.getAns());

    return 0;
}

你可能感兴趣的:(AC自动机)