P4052 文本生成器

P4052 文本生成器

题意:

给出n个单词,求至少包含其中一个单词的固定长度的文章的数量。

思路:

如果是求,怎么组成使得一个子串都没有的话,就很好求,如果当前位置到达了,单词末尾的话,就舍掉就可以了,但是,这里是求至少包含一个单词的固定长度的文章的数量,怎么办呢?

相当一个字符串,要么就是至少包含一个单词的要么就是不包含的,所以拿总的数量-一个都不包含的数量,得到就是最终题目所求的数量。

实现:

#include <stdio.h>
#include <algorithm>
#include <cstring>
using namespace std;
const long long N = 10005, mod = 1e4 + 7;
long long tr[N][26], cnt[N], idx = 1, nex[N], q[N];
char s[N];
//到第i位,匹配到j
long long f[105][N];
void insert() //字典树中插入字符串
{
    long long p = 0;
    long long len = strlen(s + 1);
    for (long long i = 1; i <= len; i++)
    {
        long long t = s[i] - 'A';
        if (!tr[p][t])
            tr[p][t] = idx++;
        p = tr[p][t];
    }
    cnt[p] = 1;
}
//构造nex数组
void build()
{
    long long hh = 1, tt = 0;
    for (long long i = 0; i < 26; i++)
        if (tr[0][i])
            q[++tt] = tr[0][i];
    while (hh <= tt)
    {
        long long t = q[hh++];
        for (long long i = 0; i < 26; i++)
        {
            //注意下面要改变tr[t][i]值,所以要加引号
            long long &p = tr[t][i];
            if (!p)
                p = tr[nex[t]][i];
            else
            {
                nex[p] = tr[nex[t]][i];
                q[++tt] = p;
                cnt[p] |= cnt[nex[p]];
            }
        }
    }
}
int main()
{
    long long n, m;
    scanf("%lld%lld", &n, &m);
    for (long long i = 1; i <= n; i++)
    {
        scanf("%s", s + 1);
        insert();
    }
    build();
    f[0][0] = 1;
    for (long long i = 1; i <= m; i++)
        for (long long j = 0; j < idx; j++)
            for (long long k = 0; k < 26; k++)
            {
                if (cnt[tr[j][k]])
                    continue;
                f[i][tr[j][k]] = (f[i - 1][j] + f[i][tr[j][k]]) % mod;
            }
    long long res = 0;
    for (long long i = 0; i < idx; i++)
        res = (res + f[m][i]) % mod;
    long long sum = 1;
    for (long long i = 1; i <= m; i++)
        sum = (sum * 26) % mod;
    printf("%lld\n", ((sum - res) % mod + mod) % mod);
    return 0;
}

posted @ 2022-08-07 18:00  zxr000  阅读(31)  评论(0编辑  收藏  举报