• BZOJ 1009: [HNOI2008]GT考试


    妈耶之前因为不熟KMP一直觉得这题好难,现在发现当年真是naive

    首先我们容易设出一个DP,(f_{i,j})表示准考证上前(i)位的长度为(j)的后缀与不吉利的数字的长度为(j)的前缀匹配的方案数

    那么显然(ans=sum_{i=0}^{m-1} f_{n,i}),考虑(f)如何转移

    假设现在做到(i)的位置,(f_{i-1})显然是已知的,那么就考虑多加入一个数字会带来什么影响

    由于这里DP的特性,我们设一个(g_{i,j})表示在不吉利的数字串上匹配时,加入一个数字,能加入多少种,使得长度为(i)的匹配变成长度为(j)的匹配

    画画图就会发现原来和准考证号匹配的是前缀,而这里加入的是后缀,因此就是个最大前缀后缀匹配的问题,这就是一个裸KMP啊

    然后我们轻易地求出了(g),然后发现这个转移就是个矩乘的形式,因此直接做就好了

    #include<cstdio>
    #include<cstring>
    #define RI register int
    #define Ms(f,x) memset(f,x,sizeof(f))
    using namespace std;
    const int R=25;
    struct Matrix
    {
        int n,m,a[R][R];
        Matrix(int N=0,int M=0) { n=N; m=M; Ms(a,0); }
        inline void Cir_init(void)
        {
            for (RI i=0;i<n;++i) a[i][i]=1;
        }
    }; int n,m,mod,next[R],ans; char s[R];
    inline void KMP(void)
    {
        int len=0; for (RI i=2;i<=m;++i)
        {
            while (len&&s[len+1]!=s[i]) len=next[len];
            if (s[len+1]==s[i]) ++len; next[i]=len;
        }
    }
    inline void inc(int &x,int y)
    {
        if ((x+=y)>=mod) x-=mod;
    }
    inline Matrix operator *(Matrix A,Matrix B)
    {
        Matrix C(A.n,B.m); for (RI i=0;i<A.n;++i)
        for (RI j=0;j<B.m;++j) for (RI k=0;k<A.m;++k)
        inc(C.a[i][j],1LL*A.a[i][k]*B.a[k][j]%mod); return C;
    }
    inline Matrix operator ^(Matrix A,int p)
    {
        Matrix T(m,m); T.Cir_init();
        for (;p;p>>=1,A=A*A) if (p&1) T=T*A; return T;
    }
    int main()
    {
        RI i,j; scanf("%d%d%d%s",&n,&m,&mod,s+1); Matrix A(m,m);
        for (KMP(),i=0;i<m;++i) for (j=0;j<10;++j)
        {
            int len=i; while (len&&s[len+1]-'0'!=j) len=next[len];
            if (s[len+1]-'0'==j) ++len; inc(A.a[i][len],1);
        }
        A=A^n; for (i=0;i<m;++i) inc(ans,A.a[0][i]);
        return printf("%d",ans),0;
    }
    
  • 相关阅读:
    我对软件工程的理解
    性能分析优化的道与术
    如何进行项目管理?
    如何进行项目管理?
    软件工程基础知识总结
    我经历过的监控系统演进史
    我对软件工程的理解
    10.14:线上直播问题汇总答疑
    软件工程基础知识总结
    如何进行需求分析?
  • 原文地址:https://www.cnblogs.com/cjjsb/p/12245476.html
Copyright © 2020-2023  润新知