HDU2896病毒入侵AC_自动机

 

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 130;
struct node{
    bool flg;
    int id;
    node *next[maxn],*fail;
    void Node(){
        fail = NULL;
        flg = false;
        memset(next,NULL,sizeof(next));
    }
}arr[500000],*que[500000];
int vis[505],num[10],cnt;
char str[10000];
void insert(int num,char *str){
    node *p = &arr[0];
    while( *str ){
        int k = *str++ - 31;
        if( !p->next[k]){
            arr[++cnt].Node();
            p->next[k] = &arr[cnt];
        }
        p = p->next[k];
    }
    p->flg = true;
    p->id = num;
}
void build_AC(){
    node *root = &arr[0],*tmp,*p;
    int head = 0,tail = 0;
    for(int i = 0; i < maxn; i++){
        if( !root->next[i] )continue;
        root->next[i]->fail = root;
        que[head++] = root->next[i];
    }
    while( head != tail){
        tmp = que[tail++];
        for(int i = 0; i < maxn; i++){
            if( !tmp->next[i] )continue;
            p = tmp->fail;
            while( p ){
                if( p->next[i]){
                    tmp->next[i]->fail = p->next[i];
                    break;
                }
                p = p->fail;
            }
            if(!p)tmp->next[i]->fail = root;
            que[head++] = tmp->next[i];
        }
    }
}
int query(char *str){
    int ans = 0;
    node *p = &arr[0],*root = &arr[0];
    while( *str ){
        int k = *str++ - 31;
        while( !p->next[k] && p != root)p = p->fail;
        p = p->next[k];
        p = p ? p : root;
        node *tmp = p;
        while( tmp != root && !vis[tmp->id]){
            if( tmp->flg && !vis[tmp->id] ){
                vis[tmp->id] = 1;
                num[ans++] = tmp->id;
            }
            tmp = tmp->fail;
        }
    }
    return ans;
}
int main(){
    int n;
    char ch[205];
    while( ~scanf("%d",&n)){
        for(int i = 1; i <= n; i++){
            scanf("%s",ch);
            insert(i,ch);
        }
        int total = 0;
        build_AC();
        scanf("%d",&n);
        for(int i = 1; i <= n; i++){
            scanf("%s",str);
            memset(vis,0,sizeof(vis));
            int ans = query(str);
            if( ans ){
                total ++;
                sort(num,num+ans);
                printf("web %d:",i);
                for(int j = 0; j < ans; j++){
                    printf(" %d",num[j]);
                }
                puts("");
            }
        }
        printf("total: %d\n",total);
    }
    return 0;
}

  

转载于:https://www.cnblogs.com/LUO257316/p/3247149.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值