• AC模版


    hdu 2222:

    #include<cstdio>
    #include<cstring>
    #define mm 88888
    #define mn 55
    #define N 26
    int tire[mm][N];
    int fail[mm],w[mm],Q[mm];
    int cg[128];
    int size;
    char tmp[mn],s[1111111];
    void build(char *word){
        int i=0,j;
        for(;*word;++word,i=tire[i][j])
            if(!tire[i][j=cg[*word]]){
                memset(tire[size],0,sizeof(tire[size]));
                w[tire[i][j]=size++]=0;
            }
        ++w[i];
    }
    void AC(){
        int *l=Q,*r=Q,i,j,k;
        for(i=0;i<N;++i)
            if(tire[0][i])fail[*r++=tire[0][i]]=0;
        for(;l!=r;++l)
            for(i=*l,j=0;j<N;++j)
                if(k=tire[i][j])fail[*r++=k]=tire[fail[i]][j];
                else tire[i][j]=tire[fail[i]][j];
    }
    int main(){
        int i,j,r,n,T,ans;
        for(fail[0]=i=0; i<26; ++i)cg[i+'a']=i;
        scanf("%d",&T);
        while(T--){
            memset(tire[0],0,sizeof(tire[0]));
            size=1;
            scanf("%d",&n),getchar();//getchar()接收换行符
            while(n--)gets(tmp),build(tmp);
            AC();
            gets(s);
            ans=i=r=0;
            while(s[r]){
                j=i=tire[i][cg[s[r++]]];
                while(j&&w[j]!=-1)
                    ans+=w[j],w[j]=-1,j=fail[j];
            }
            printf("%d\n",ans);
        }
        return 0;

    } 

    通用模版:

      #include<cstring>

    #define FF(i,a)        for( int i = 0 ; i < a ; i ++ )
    #define CC(m,what)    memset(m,what,sizeof(m))
    const int NODE = 1500;
    const int CH = 4;
    int chd[NODE][CH] , sz;//结点个数
    int word[NODE];//关键数组,记录每个单词尾结点的信息,每道题目都不一样
    int fail[NODE];//传说中的失败指针
    int Que[NODE];//辅助队列
    int sw[128];//string swap每个字符对应的Index,方便模板化

    void Ins(char *a, int val) {
        int p = 0;
        for(; *a ; a ++) {
            int c = sw[*a];
            if(!chd[p][c]) {
                CC(chd[sz] , 0);
                word[sz] = 0;
                chd[p][c] = sz ++;
            }
            p = chd[p][c];
        }
        word[p] = val;
    }
    void AC() {
        int *s = Que , *e = Que;
        FF(i,CH) if(chd[0][i]) {
            fail[ chd[0][i] ] = 0;
            *e++ = chd[0][i];
        }
        while(s != e) {
            int p = *s++;
            FF(i,CH) {
                if(chd[p][i]) {
                    int v = chd[p][i];
                    *e++ = v;
                    fail[v] = chd[fail[p]][i];
                    //对word[v]按word[fail[v]]里的内容进行处理
                } else {
                    chd[p][i] = chd[fail[p]][i];
                }
            }
        }
    }
    //AC()函数处理后    chd[p][i] 就是在p结点进行i转移到达的结点
    int main() {
        fail[0] = 0;
        FF(i,26) sw[i+'a'] = i;
    //下面两句每次都必须初始化
        CC(chd[0],0);
        sz = 1;
    }
  • 相关阅读:
    vs2005 水晶报表横向打印Bug
    petshop4.0 详解之七(PetShop表示层设计)
    petshop4.0 详解之八(PetShop表示层设计)
    在VS2005中使用VSS2005
    用DataFormatString格式化GridView
    GridView的高级用法
    水晶报表 打印时出现错误提示:出现通信错误。将停止打印
    POJ1182 食物链[并查集]
    并查集的基础知识
    HDOJ1269 迷宫城堡[强连通分量]
  • 原文地址:https://www.cnblogs.com/xiaolongchase/p/2256321.html
Copyright © 2020-2023  润新知