【AC自动机】[HDU2896]病毒侵袭

题目大意:多组询问的AC自动机
这里注意一下在HDU2222的基础上修改一下不要把FLAG清零,同时用一个数组记录一下那些出现过就行了

#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 = 500;
struct State{
    int fail, flag;
    int ch[128];
}p[MAXN*200+30];
int scnt, Bef[MAXN*200+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]]){
            p[now].ch[s[i]] = ++scnt;
            now = scnt;
        }else now = p[now].ch[s[i]];
    }
    p[now].flag = id;
}
void _initTree(){
    queue<int> que;
    for(int i=0;i<128;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<128;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[10010];
bool ans[MAXN+20];
int match(int id){
    int len = strlen(ls);
    int u = 0, counter = 0;
    memset(ans, 0, sizeof ans);
    for(int i=0;i<len;i++){
        if(p[u].ch[ls[i]])
            u = p[u].ch[ls[i]];
        else{
            int k = p[u].fail;
            while(k && !p[k].ch[ls[i]]) k = p[k].fail;
            u = p[k].ch[ls[i]];
        }
        int k = u;
        while(k){
            if(p[k].flag){
                ans[p[k].flag] = 1;
                counter=1;
            }
            k = Bef[k];
        }
    }
    if(!counter) return 0;
    printf("web %d:", id);
    for(int i=1;i<=MAXN;i++)
        if(ans[i])
            printf(" %d", i);
    printf("\n");
    return 1;
}
int main(){
    char s[300];
    int T, n;
    scanf("%d", &T);
    for(int i=1;i<=T;i++){
        scanf("%s", s);
        Add(s, i);
    }
    _initTree();
    int tot = 0;
    scanf("%d", &n);
    rep(num, n){
        scanf("%s", ls);
        tot += match(num);
    }
    printf("total: %d\n", tot);

    return 0;
}

posted on 2015-12-22 13:33  JeremyGuo  阅读(119)  评论(0编辑  收藏  举报

导航