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;
}

你可能感兴趣的:(模版)