• [bzoj1030][JSOI2007]文本生成器【AC自动机】


    【题目链接】
      http://www.lydsy.com/JudgeOnline/problem.php?id=1030
    【题解】
      建出ac自动机,把是串的末尾的点打上标记,若一个点的fail指针指向的点(即它的后缀)有标记,那么这个点也打上标记,然后在这个ac自动机上跑dp,遇到有标记的点就不往后拓展,统计出不可以走的方案数,最后用总数减去方案数即是答案。
      

    /* --------------
        user Vanisher
        problem bzoj-1030 
    ----------------*/
    # include <bits/stdc++.h>
    # define    ll      long long
    # define    N       110
    # define    P       10007
    using namespace std;
    int read(){
        int tmp=0, fh=1; char ch=getchar();
        while (ch<'0'||ch>'9'){if (ch=='-') fh=-1; ch=getchar();}
        while (ch>='0'&&ch<='9'){tmp=tmp*10+ch-'0'; ch=getchar();}
        return tmp*fh;
    }
    struct Trie{
        int son[26],f;
        bool tag;
    }T[N*N];
    int f[N][N*N],q[N*N],place,n,m,ans;
    char s[N];
    int mypow(int x, int y){
        int i=x; x=1;
        while (y>0){
            if (y%2==1) x=x*i%P;
            i=i*i%P;
            y/=2;
        }
        return x;
    }
    void makefail(){
        int pl=1, pr=1; q[1]=0;
        while (pl<=pr){
            int x=q[pl++];
            for (int i=0; i<26; i++)
                if (T[x].son[i]!=0){
                    q[++pr]=T[x].son[i];
                //  T[T[x].son[i]].tag|=T[x].tag;
                    int p=x;
                    while (p!=0&&T[T[p].f].son[i]==0) p=T[p].f;
                    if (p==0) T[q[pr]].f=0;
                        else T[q[pr]].f=T[T[p].f].son[i];
                    if (T[T[q[pr]].f].tag==true) T[q[pr]].tag=true;
                }
        }
    }
    void extend(){
        int now=0, l=strlen(s+1);
        for (int i=1; i<=l; i++){
            if (T[now].son[s[i]-'A']==0)
                T[now].son[s[i]-'A']=++place;
            now=T[now].son[s[i]-'A'];
        }
        T[now].tag=true;
    }
    int main(){
        n=read(), m=read();
        for (int i=1; i<=n; i++){
            scanf("
    %s",s+1);
            extend();
        }
        makefail();
        f[0][0]=1;
        for (int i=1; i<=m; i++){
            for (int j=0; j<=place; j++)
                if (T[j].tag==false){
                    for (int k=0; k<26; k++){
                        int p=j;
                        while (p!=0&&T[p].son[k]==0) p=T[p].f;
                        f[i][T[p].son[k]]=(f[i][T[p].son[k]]+f[i-1][j])%P;
                    }
                }
        }
        for (int i=0; i<=place; i++)
            if (T[i].tag==false) ans=(ans+f[m][i])%P;
        ans=(mypow(26,m)-ans+P)%P;
        printf("%d
    ",ans);
        return 0;
    }
    
  • 相关阅读:
    201521123028 《Java程序设计》第5周学习总结
    Markdown格式
    201521123028《Java程序设计》第4周学习总结
    201521123028 《Java程序设计》第3周学习总结
    Spring07 JDBC
    Spring06 Aop
    Mystring05 配置文件之间的关系
    Mybatais 13 二级缓存
    Mybatais 14 注释的配置
    Mybatais 12 一级缓存
  • 原文地址:https://www.cnblogs.com/Vanisher/p/9135995.html
Copyright © 2020-2023  润新知