bzoj1030 AC自动机+dp

思路:建状态图,在状态图上dp。

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

int n, m;
char s[N];

void add(int &a, int b) {
    a += b; if(a >= mod) a -= mod;
}
struct Ac {
    int ch[N][26], dp[N][100][2], val[N], f[N], tot, sz;
    void init(int sz) {this->sz = sz, tot = 0;};
    int newNode() {
        tot++; f[tot] = 0; val[tot] = 0;
        memset(ch[tot], 0, sizeof(ch[tot]));
        return tot;
    }
    inline int idx(char c) {return c - 'A';}
    void addStr(char *s) {
        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];
        }
        val[u] = 1;
    }
    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();
            val[u] |= val[f[u]];
            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() {
        memset(dp, 0, sizeof(dp));
        dp[0][0][0] = 1;
        for(int k = 0; k < m; k++) {
            for(int u = 0; u <= tot; u++) {
                for(int c = 0; c < sz; c++) {
                    int v = ch[u][c];
                    add(dp[v][k + 1][1], dp[u][k][1]);
                    if(val[v]) add(dp[v][k + 1][1], dp[u][k][0]);
                    else add(dp[v][k + 1][0], dp[u][k][0]);
                }
            }
        }

        int ans = 0;
        for(int i = 0; i <= tot; i++)
            add(ans, dp[i][m][1]);
        printf("%d\n", ans);
    }
} ac;
int main() {
    ac.init(26);
    scanf("%d%d", &n, &m);
    for(int i = 0; i < n; i++) {
        scanf("%s", s);
        ac.addStr(s);
    }
    ac.build();
    ac.solve();
    return 0;
}


/*
2
abad
ba
-----
*/

 

posted @ 2018-08-17 10:21  NotNight  阅读(82)  评论(0编辑  收藏