bzoj 4327 AC自动机

思路:将能跑到的状态标记一下,在bfs搜一下就好啦。

#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 = 1e7 + 7;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1000000007;

int n, m, len[100007], pos[100007];
char s[N], t[101];

struct Ac {
    int ch[N][4], f[N], d[N], tot, sz;
    Ac(int sz) {this->sz = sz;}
    void init() {tot = 0;}
    int newNode() {
        tot++; f[tot] = 0;
        memset(ch[tot], 0, sizeof(ch[tot]));
        return tot;
    }
    inline int idx(char c) {
        if(c == 'E') return 0;
        if(c == 'S') return 1;
        if(c == 'W') return 2;
        if(c == 'N') return 3;
    }

    void addStr(char *s, int ID) {
        int u = 0;
        for(int i = 0; s[i]; i++) {
            int c = idx(s[i]);
            if(!ch[u][c]) ch[u][c] = newNode();
            u = ch[u][c];
        }
        pos[ID] = u;
    }

    void build() {
        queue<int> que;
        for(int c = 0; c < sz; c++) {
            int v = ch[0][c];
            if(!v) ch[0][c] = 0;
            else f[v] = 0, que.push(v);
        }
        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];
                else f[v] = ch[f[u]][c], que.push(v);
            }
        }
    }

    void solve(char *s) {
        queue<int> que;
        memset(d, -1, sizeof(d));
        int u = 0;
        d[u] = 0; que.push(u);
        for(int i = 0; s[i]; i++) {
            int c = idx(s[i]);
            u = ch[u][c];
            int p = u;
            while(p && d[p] == -1) {
                d[p] = 0; que.push(p); p = f[p];
            }
        }

        while(!que.empty()) {
            int u = que.front(); que.pop();
            for(int c = 0; c < sz; c++) {
                int v = ch[u][c];
                if(d[v] != -1) continue;
                d[v] = d[u] + 1;
                que.push(v);
            }
        }
        for(int i = 1; i <= m; i++) printf("%d\n", len[i] - d[pos[i]]);
    }
} ac(4);

int main() {
    ac.init();
    scanf("%d%d", &n, &m);
    scanf("%s", s);
    for(int i = 1; i <= m; i++) {
        scanf("%s", t);
        ac.addStr(t, i);
        len[i] = strlen(t);
    }
    ac.build();
    ac.solve(s);
    return 0;
}


/*
*/

 

posted @ 2018-08-17 16:40  NotNight  阅读(122)  评论(0编辑  收藏  举报