• hdu 3065 病毒侵袭持续中 (AC)


    http://acm.hdu.edu.cn/showproblem.php?pid=3065 

    AC自动机,主要注意的就是两个特征码的重叠情况。

    code:

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    using namespace std ;
    const int kind = 30;
    struct node{
        node *fail ;
        node *next[kind] ;
        int count ;
        int id ;
        node(){
           fail = NULL ;
           count = 0 ;
           id = -1 ;
           memset(next, NULL, sizeof(next)) ;
       }
    }*q[500001] ;
    char keyword[1001][51] ;
    char str[2000001] ;
    int head, tail, ID ;
    int vis[1001] ;

    void insert(char *str, node *root){
        node *p = root ;
        int i = 0, index ;
        while(str[i]){
            index = str[i] - 'A' ;
            if(p->next[index]==NULL) p->next[index]=new node() ;
            p = p->next[index] ;
            i ++ ;
        }
        p->count ++ ;
        p->id = ID ++ ;
    }
    void build_ac_automation(node *root){
        int i ;
        root->fail = NULL ;
        q[head++] = root ;
        while(head!=tail){
            node *temp = q[tail++] ;
            node *p = NULL ;
            for(i=0; i<30; i++){
                if(temp->next[i]!=NULL){
                    if(temp==root) temp->next[i]->fail = root ;
                    else{
                        p = temp->fail ;
                        while(p!=NULL){
                            if(p->next[i]!=NULL){
                                temp->next[i]->fail = p->next[i] ;
                                break ;
                            }
                            p = p->fail ;
                        }
                        if(p==NULL) temp->next[i]->fail = root ;
                    }
                    q[head++] = temp->next[i] ;
                }
            }
        }
    }
    void query(node *root){
        int i = 0, index ;
        node *p = root ;
        while(str[i]){
            index = str[i] - 'A' ;
            if(index<0||index>26)
                index = 27 ;
            while(p->next[index]==NULL && p!=root)
                p = p->fail ;
            p = p->next[index] ;
            p = (p==NULL) ? root : p ;
            node *temp = p ;
            while(temp!=root){
                if(temp->id!=-1)
                    vis[temp->id] ++ ;
                temp = temp->fail ;
            }
            i ++ ;
        }
    }
    int main(){
        int n ;
        while(~scanf("%d", &n)){
            memset(vis, 0sizeof(vis)) ;
            head = tail = 0 ;
            ID = 0 ;
            node *root = new node() ;
            for(int i=0; i<n; i++){
                getchar() ;
                scanf("%s", keyword[i]) ;
                insert(keyword[i], root) ;
            }
            build_ac_automation(root) ;
            getchar() ;
            scanf("%s", str) ;
            query(root) ;
            for(int i=0; i<n; i++)
                if(vis[i])
                    printf("%s: %d\n", keyword[i], vis[i]) ;
        }
        return 0 ;} 
  • 相关阅读:
    [ZJOI2010]count 数字计数
    小雄数
    简单筛法函数
    [Noip模拟题]lucky
    欧拉线筛
    Intern Day78
    CodeForces1360C
    CodeForces1373B
    Intern Day78
    Intern Day78
  • 原文地址:https://www.cnblogs.com/xiaolongchase/p/2362438.html
Copyright © 2020-2023  润新知