初学AC自动机

Posted ccut-ry

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了初学AC自动机相关的知识,希望对你有一定的参考价值。

推荐博客 : https://blog.csdn.net/Whispers_zmf/article/details/80809609

    http://www.cnblogs.com/Kv-Stalin/p/9443622.html

 

HDU 2222

const int maxn = 5e5+5;

int n;
char s[105];
int c[maxn][26];
int fail[maxn], val[maxn], last[maxn];
int rt = 0;
char p[maxn<<1];

void init(){
    rt = 1;
    memset(val, 0, sizeof(val));
    memset(c, 0, sizeof(c));
}
void insert(){
    int len = strlen(s+1);
    int u = 0, v;
    
    for(int i = 1; i <= len; i++){
        v = s[i]-‘a‘;
        if (!c[u][v]) c[u][v] = rt++;
        u = c[u][v];
    }
    val[u]++;
}
queue<int>que;
void build(){
    while(!que.empty()) que.pop();
    for(int i = 0; i < 26; i++){
        if (c[0][i]) {
            fail[c[0][i]] = 0;
            que.push(c[0][i]);
        }
    }
    while(!que.empty()){
        int now = que.front(); que.pop();
        for(int i = 0; i < 26; i++){
            if (c[now][i]){
                fail[c[now][i]] = c[fail[now]][i];
                que.push(c[now][i]);    
                //last[now] = val[fail[now]]?fail[now]:last[fail[now]];
            }
            else c[now][i] = c[fail[now]][i];
        }
    }
}
int ans;
void query(){
    int len = strlen(p+1);
    int u = 0, v;
    
    for(int i = 1; i <= len; i++){
        v = p[i]-‘a‘;
        u = c[u][v];
        for(int j = u; j && ~val[j]; j = fail[j]) {
            ans += val[j];
            val[j] = -1;
        }
    } 
}

int main() { 
    int t;
    
    cin >> t;
    while(t--){
        cin >> n;
        init();
        for(int i = 1; i <= n; i++){
            scanf("%s", s+1);
            insert();
        }
        build();
        scanf("%s", p+1);
        ans = 0;
        query();
        printf("%d
", ans);
    }
    return 0;
}

 

以上是关于初学AC自动机的主要内容,如果未能解决你的问题,请参考以下文章

POJ3691DNA repair(AC自动机,DP)

初学AC自动机

HDU4057 Rescue the Rabbit(AC自动机+状压DP)

Codeforces 86C Genetic engineering(AC自动机+DP)

模板AC自动机

POJ1699 Best Sequence(AC自动机+状压DP)