zoukankan      html  css  js  c++  java
  • BZOJ 1030 文本生成器 | 在AC自动机上跑DP

    题目:

    http://www.lydsy.com/JudgeOnline/problem.php?id=1030


    题解:

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #define p 10007
    #define N 6010
    using namespace std;
    int n,m,sze=1,ans1,ans2=1,a[N][27],fail[N],q[N],f[110][N];
    char s[110];
    bool is[N];
    void insert()
    {
        int now=1,ch,l=strlen(s);
        for(int i=0;i<l;i++)
        {
        ch=s[i]-'A'+1;
        if(a[now][ch]) now=a[now][ch];
        else now=a[now][ch]=++sze;
        }
        is[now]=1;
        return ;
    }
    void acmatch()
    {
        int l=0,r=1,now;
        q[0]=1;fail[1]=0;
        while(l<r)
        {
        now=q[l++];
        for(int i=1;i<=26;i++)
        {
            if(!a[now][i]) continue;
            int k=fail[now];
            while(!a[k][i]) k=fail[k];
            fail[a[now][i]]=a[k][i];
            if (is[a[k][i]])
            is[a[now][i]]=1;
            q[r++]=a[now][i];
        }
        }
    }
    void dp(int x)
    {
        for (int i=1;i<=sze;i++)
        {
        if (is[i] || !f[x-1][i]) continue;
        for (int j=1;j<=26;j++)
        {
            int k=i;
            while (!a[k][j]) k=fail[k];
            f[x][a[k][j]]=(f[x][a[k][j]]+f[x-1][i])%p;
        }
        }
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for (int i=1;i<=26;i++) a[0][i]=1;
        for (int i=1;i<=n;i++)
        {
        scanf("%s",s);
        insert();
        }
        acmatch();
        f[0][1]=1;
        for (int i=1;i<=m;i++) dp(i);
        for (int i=1;i<=m;i++)
        ans2=ans2*26%p;
        for(int i=1;i<=sze;i++)
        if(!is[i]) ans1=(ans1+f[m][i])%p;
        printf("%d",(ans2-ans1+p)%p);
        return 0;
    }
  • 相关阅读:
    二进制编译http
    http服务
    FTP服务
    DAY01
    直流电机调速作业
    机械大楼电梯控制项目
    仿真作业
    第六周作业
    第五周作业
    第四周仿真作业
  • 原文地址:https://www.cnblogs.com/mrsheep/p/8242738.html
Copyright © 2011-2022 走看看