【AC自动机】[HDU3065]病毒侵袭持续中

本来很简单的一道题目,和病毒侵袭差不多,只不过把bool ans 改成了int ans 然后统计一下次数就好了, 但是题目中居然没有出现多组数据的提示。。。。Wa了N次,居然因为没有多组数据。。。

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
#include <iostream>
using namespace std;
#define rep(i,k) for(int (i)=1;(i)<=(k);(i)++)
const int MAXN = 1000;
struct State{
    int fail, flag;
    int ch[26];
}p[MAXN*50+30];
int scnt, Bef[MAXN*50+30];
void Add(char *s, int id){
    int now = 0, len = strlen(s);
    for(int i=0;i<len;i++){
        if(!p[now].ch[s[i]-'A'])
            p[now].ch[s[i]-'A'] = ++scnt;
         now = p[now].ch[s[i]-'A'];
    }
    p[now].flag = id;
}
void _initTree(){
    queue<int> que;
    for(int i=0;i<26;i++)
        if(p[0].ch[i])
            que.push(p[0].ch[i]);
    while(!que.empty()){
        int u = que.front();
        que.pop();
        for(int i=0;i<26;i++) if(p[u].ch[i]){
            int v = p[u].ch[i];
            que.push(v);
            int k = p[u].fail;
            while(k && !p[k].ch[i]) k = p[k].fail;
            p[v].fail = p[k].ch[i];
            Bef[v] = p[p[v].fail].flag > 0 ? p[v].fail : Bef[p[v].fail];
        }
    }
}
char ls[2000010];
int ans[MAXN+20];
void match(){
    int len = strlen(ls);
    int u = 0, ids;
    memset(ans, 0, sizeof ans);
    for(int i=0;i<len;i++){
        if(ls[i] < 'A' || ls[i] > 'Z'){
            u = 0;
            continue;
        }
        ids = ls[i] - 'A';
        if(p[u].ch[ids])
            u = p[u].ch[ids];
        else{
            int k = p[u].fail;
            while(k && !p[k].ch[ids]) k = p[k].fail;
            u = p[k].ch[ids];
        }
        int k = u;
        while(k){
            if(p[k].flag)
                ans[p[k].flag]++;
            k = Bef[k];
        }
    }
}
char s[MAXN+10][60];
void _init(int n){
    for(int i=0;i<=n;i++){
        ans[i] = 0;
        p[i].flag = p[i].fail = 0;
        memset(p[i].ch, 0, sizeof p[i].ch);
    }
    memset(Bef, 0, sizeof Bef);
    scnt=0;
}
int main(){
    int T;
    while(scanf("%d", &T) != EOF){
        _init(T*50+10);
        rep(i, T){
            scanf("%s", s[i]);
            Add(s[i], i);
        }
        _initTree();
        scanf("%s", ls);
        match();
        rep(i, T){
            if(!ans[i]) continue;
            printf("%s: %d\n", s[i], ans[i]);
        }
    }

    return 0;
}

你可能感兴趣的:(算法,字符串,树,AC自动机)