bzoj 1030: [JSOI2007]文本生成器

AC自动机上跑DP 

注意的细节是fail链上有标记 该节点也要标记(就好比 “ ********123******** ”  索然最后没有出现123 但是中间出现了123  这种情况不可取!) 

/**************************************************************
    Problem: 1030
    User: lxy8584099
    Language: C++
    Result: Accepted
    Time:132 ms
    Memory:6044 kb
****************************************************************/
 
/*
    有点像 1009 TG考试 不过这个数据挺小 不用矩阵加速 
    我们求出不合法的个数 用总数减去就行了
    一个串的时候我们用KMP转移 
    因为有多个串 所以建个AC自动机 转移 
    之后的就和1009一模一样了
    f[i][j]表示 表示前i个字符 目前节点为j 的不符合方案数
    转移: f[i][ c[j][k] ] += f[i-1][j] (c[j][k]不是某个认识单词的结尾) 
    自动机没有儿子自动接上fail 方便!!! 
    考虑到如果某节点fail链跳到 0 的路上也遇到标记的话 
        这个点也是不可取的! 
        处理方法:我们在自动机上用或运算。 
*/
#include<queue>
#include<cstdio>
#include<cstring>
using namespace std;
const int N=1e4+50;
const int MOD=10007;
int c[N][26],last[N],n,m,tot;
int f[105][N],ans=0,sum=1;
bool vis[N];
void Add(char *s)
{
    int l=strlen(s),u=0;
    for(int i=0;i<l;i++)
    {
        int v=s[i]-'A';
        if(!c[u][v]) c[u][v]=++tot;
        u=c[u][v];
    } vis[u]=1;
}
void Init()
{
    scanf("%d%d",&n,&m);char s[105];
    for(int i=1;i<=n;i++) scanf("%s",s),Add(s);
}
void Ac_build()
{
    queue<int> q;
    for(int i=0;i<26;i++)
        if(c[0][i]) q.push(c[0][i]);
    while(!q.empty())
    {
        int u=q.front();q.pop();
        for(int v=0;v<26;v++)
        {
            if(c[u][v])
            {
                last[c[u][v]]=c[last[u]][v];
                vis[c[u][v]]|=vis[c[last[u]][v]];
                // fial链有标记 该节点不能到达! 
                q.push(c[u][v]);continue;
            }
            c[u][v]=c[last[u]][v]; // 这叫啥。。忘了。 
        }
             
    }
}
void Solve() 
{
    f[0][0]=1;
    for(int i=0;i<m;i++)
        for(int u=0;u<=tot;u++)
            for(int v=0;v<26;v++) if(!vis[c[u][v]])
                (f[i+1][c[u][v]]+=f[i][u])%=MOD;
    for(int i=0;i<=tot;i++) (ans+=f[m][i])%=MOD;
    for(int i=1;i<=m;i++) (sum*=26)%=MOD;
    printf("%d\n",(sum-ans+MOD)%MOD);
}
int main()
{
    Init();
    Ac_build();
    Solve();
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/lxy8584099/p/10191955.html
今日推荐