ac自动机模板

只有失配链接

#include<bits/stdc++.h>
#define LL long long
#define ll long long
#define fi first
#define se second
#define mk make_pair
#define pii pair<int, int>
#define y1 skldjfskldjg
#define y2 skldfjsklejg

using namespace std;

const int N = 1e6 + 7;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9 + 7;

int n;
char s[N];
struct Ac {
    int val[N], ch[N][26], f[N], cnt, SZ;

    void init(int SZ = 26) {
        cnt = 0; this->SZ = SZ;
        for(int c = 0; c < SZ; c++) ch[0][c] = 0;
    }

    int getId(char c) {
        return c - 'a';
    }

    int newNode() {
        cnt++;
        memset(ch[cnt], 0, sizeof(ch[cnt]));
        val[cnt] = f[cnt] = 0;
        return cnt;
    }

    void add(char *s) {
        int u = 0;
        for(int i = 0; s[i]; i++) {
            int c = getId(s[i]);
            if(!ch[u][c]) ch[u][c] = newNode();
            u = ch[u][c];
        }
        val[u]++;
    }

    void build() {
        queue<int> que;
        f[0] = 0;
        for(int c = 0; c < SZ; c++) {
            if(!ch[0][c]) continue;
            f[ch[0][c]] = 0;
            que.push(ch[0][c]);
        }
        while(!que.empty()) {
            int u = que.front(); que.pop();
            for(int c = 0; c < SZ; c++) {
                if(!ch[u][c]) continue;
                int v = ch[u][c], w = f[u];
                while(w && !ch[w][c]) w = f[w];
                f[v] = ch[w][c];
                que.push(v);
            }
        }
    }

    LL cal(char *s) {
        LL ans = 0;
        for(int i = 0, j; s[i]; i++) {
            int c = getId(s[i]);
            while(j && !ch[j][c]) j = f[j];
            j = ch[j][c];
            int p = j;
            while(p && val[p] != -1) {
                ans += val[p];
                val[p] = -1;
                p = f[p];
            }
        }
        return ans;
    }
} ac;

int main() {
    int T; scanf("%d", &T);
    while(T--) {
        ac.init(26);
        scanf("%d", &n);
        for(int i = 1; i <= n; i++) {
            scanf("%s", s);
            ac.add(s);
        }

        ac.build();

        scanf("%s", s);
        printf("%lld\n", ac.cal(s));
    }
    return 0;
}
View Code

 

有后缀链接

#include<bits/stdc++.h>
#define LL long long
#define ll long long
#define fi first
#define se second
#define mk make_pair
#define pii pair<int, int>
#define y1 skldjfskldjg
#define y2 skldfjsklejg

using namespace std;

const int N = 1e6 + 7;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9 + 7;

int n;
char s[N];
struct Ac {
    int val[N], ch[N][26], f[N], last[N], cnt, SZ;

    void init(int SZ = 26) {
        cnt = 0; this->SZ = SZ;
        for(int c = 0; c < SZ; c++) ch[0][c] = 0;
    }

    int getId(char c) {
        return c - 'a';
    }

    int newNode() {
        cnt++;
        memset(ch[cnt], 0, sizeof(ch[cnt]));
        val[cnt] = f[cnt] = last[cnt] = 0;
        return cnt;
    }

    void add(char *s) {
        int u = 0;
        for(int i = 0; s[i]; i++) {
            int c = getId(s[i]);
            if(!ch[u][c]) ch[u][c] = newNode();
            u = ch[u][c];
        }
        val[u]++;
    }

    void build() {
        queue<int> que;
        f[0] = 0;
        for(int c = 0; c < SZ; c++) {
            if(!ch[0][c]) continue;
            f[ch[0][c]] = last[ch[0][c]] = 0;
            que.push(ch[0][c]);
        }
        while(!que.empty()) {
            int u = que.front(); que.pop();
            for(int c = 0; c < SZ; c++) {
                if(!ch[u][c]) continue;
                int v = ch[u][c], w = f[u];
                while(w && !ch[w][c]) w = f[w];
                f[v] = ch[w][c];
                last[v] = val[f[v]] ? f[v] : last[f[v]];
                que.push(v);
            }
        }
    }

    LL cal(char *s) {
        LL ans = 0;
        for(int i = 0, j; s[i]; i++) {
            int c = getId(s[i]);
            while(j && !ch[j][c]) j = f[j];
            j = ch[j][c];
            int p = j;
            while(p && val[p] != -1) {
                ans += val[p];
                val[p] = -1;
                p = last[p];
            }
        }
        return ans;
    }
} ac;

int main() {
    int T; scanf("%d", &T);
    while(T--) {
        ac.init(26);
        scanf("%d", &n);
        for(int i = 1; i <= n; i++) {
            scanf("%s", s);
            ac.add(s);
        }

        ac.build();

        scanf("%s", s);
        printf("%lld\n", ac.cal(s));
    }
    return 0;
}
View Code

 

改造版本

#include<bits/stdc++.h>
#define LL long long
#define ll long long
#define fi first
#define se second
#define mk make_pair
#define pii pair<int, int>
#define y1 skldjfskldjg
#define y2 skldfjsklejg

using namespace std;

const int N = 1e6 + 7;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9 + 7;

int n;
char s[N];
struct Ac {
    int val[N], ch[N][26], f[N], last[N], cnt, SZ;

    void init(int SZ = 26) {
        cnt = 0; this->SZ = SZ;
        for(int c = 0; c < SZ; c++) ch[0][c] = 0;
    }

    int getId(char c) {
        return c - 'a';
    }

    int newNode() {
        cnt++;
        memset(ch[cnt], 0, sizeof(ch[cnt]));
        val[cnt] = f[cnt] = last[cnt] = 0;
        return cnt;
    }

    void add(char *s) {
        int u = 0;
        for(int i = 0; s[i]; i++) {
            int c = getId(s[i]);
            if(!ch[u][c]) ch[u][c] = newNode();
            u = ch[u][c];
        }
        val[u]++;
    }

    void build() {
        queue<int> que;
        f[0] = 0;
        for(int c = 0; c < SZ; c++) {
            if(!ch[0][c]) continue;
            f[ch[0][c]] = last[ch[0][c]] = 0;
            que.push(ch[0][c]);
        }
        while(!que.empty()) {
            int u = que.front(); que.pop();
            for(int c = 0; c < SZ; c++) {
                int v = ch[u][c];
                if(!v) {
                    ch[u][c] = ch[f[u]][c];
                    continue;
                } else {
                    que.push(v);
                    f[v] = ch[f[u]][c];
                    last[v] = val[f[v]] ? f[v] : last[f[v]];
                }
            }
        }
    }

    LL cal(char *s) {
        LL ans = 0;
        for(int i = 0, j; s[i]; i++) {
            int c = getId(s[i]);
            j = ch[j][c];
            int p = j;
            while(p && val[p] != -1) {
                ans += val[p];
                val[p] = -1;
                p = last[p];
            }
        }
        return ans;
    }
} ac;

int main() {
    int T; scanf("%d", &T);
    while(T--) {
        ac.init(26);
        scanf("%d", &n);
        for(int i = 1; i <= n; i++) {
            scanf("%s", s);
            ac.add(s);
        }

        ac.build();

        scanf("%s", s);
        printf("%lld\n", ac.cal(s));
    }
    return 0;
}
View Code

 

posted @ 2018-08-12 14:57  NotNight  阅读(139)  评论(0编辑  收藏  举报