zoukankan      html  css  js  c++  java
  • BZOJ1030 文本生成器(AC自动机+DP)

    求长度为(m)的包含至少一个模式串的字符串数量


    考虑长度为(m)的不包含任何模式串的字符串数量
    (dp[i][j])表示当前长度为(i),匹配到(Trie)(j)节点的答案

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int maxn = 6010;
    const int mod = 1e4 + 7;
    int n, m;
    int bin(int x, int y) {
        int ans = 1;
        for (; y; y >>= 1, x = (ll)x * x % mod)
            if (y & 1) ans = (ll)ans * x, ans %= mod;
        return ans;
    }
    struct Trie {
        int next[maxn][26], fail[maxn], end[maxn];
        int last[maxn];
        int dp[110][maxn];
        int root, L;
        int newnode() {
            for (int i = 0; i < 26; i++)
                next[L][i] = -1;
            fail[L] = last[L] = end[L] = 0;
            return L++;
        }
        void init() {
            L = 0;
            root = newnode();
        }
        void insert(char buf[]) {
            int len = strlen(buf);
            int now = root;
            for (int i = 0; i < len; i++) {
                if (next[now][buf[i] - 'A'] == -1)
                    next[now][buf[i] - 'A'] = newnode();
                now = next[now][buf[i] - 'A'];
            }
            end[now]++;
        }
        void build() {
            queue<int> Q;
            fail[root] = root;
            for (int i = 0; i < 26; i++) {
                if (next[root][i] == -1)
                    next[root][i] = root;
                else {
                    fail[next[root][i]] = root;
                    Q.push(next[root][i]);
                }
            }
            while (!Q.empty()) {
                int now = Q.front();
                Q.pop();
                end[now] += end[fail[now]];
                for (int i = 0; i < 26; i++) {
                    if (next[now][i] == -1)
                        next[now][i] = next[fail[now]][i];
                    else {
                        int son = next[now][i];
                        fail[son] = next[fail[now]][i];
                        last[son] = end[fail[son]] ? fail[son] : last[fail[son]];
                        Q.push(next[now][i]);
                    }
                }
            }
        }
        void solve() {
            dp[0][0] = 1;
            for (int i = 1; i <= m; i++) {
                for (int j = 0; j < L; j++) {
                    for (int k = 0; k < 26; k++) {
                        if (end[next[j][k]]) continue;
                        dp[i][next[j][k]] += dp[i - 1][j];
                        dp[i][next[j][k]] %= mod;
                    }
                }
            }
            int ans = 0;
            for (int i = 0; i < L; i++) {
                ans += dp[m][i];
                ans %= mod;
            }
            printf("%d
    ", ((bin(26, m) - ans) % mod + mod) % mod);
        }
    } ac;
    char s[maxn];
    int main() {
        ac.init();
        scanf("%d%d", &n, &m);
        for (int i = 0; i < n; i++) {
            scanf("%s", s);
            ac.insert(s);
        }
        ac.build();
        ac.solve();
        return 0;
    }
    
  • 相关阅读:
    mysql 严格模式 Strict Mode
    PHP中NULL和‘'的区别
    nginx 出现413 Request Entity Too Large问题的解决方法
    mysql 转换NULL数据方法
    mysql大小写敏感配置
    mysql导入大批量数据出现MySQL server has gone away的解决方法
    mysql函数concat与group_concat使用说明
    Linux下aMule安装教程
    四、YOLO-V1原理与实现(you only look once)
    tf.cast(ndarray,dtype)
  • 原文地址:https://www.cnblogs.com/Zeronera/p/13855293.html
Copyright © 2011-2022 走看看