zoukankan      html  css  js  c++  java
  • bzoj 1009: [HNOI2008]GT考试【kmp+dp+矩阵快速幂】

    看n和k的范围长得就很像矩阵乘法了
    设f[i][j]表示到第i个位置的后缀最长匹配目标串的j位。转移的话显然是枚举0~9,然后选择f[i+1]中能被他转移的加起来,需要用到next数组。然后构造矩阵的时候,在转移路径上++即可(注意代码里的f数组只是辅助构造矩阵的,和上文无关
    在写挂了n次kmp之后我突然意识到一个问题:k<=20,我随便暴力个5、6次方的都没问题为啥要kmp……
    结果还是用了kmp

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int M=30;
    int n,m,mod,c[M],ne[M],f[M][M],an;
    char s[M];
    struct qwe
    {
        int a[M][M];
        void init()
        {
            memset(a,0,sizeof(a));
        }
        qwe operator * (const qwe &b) const
        {
            qwe c;
            c.init();
            for(int k=0;k<m;k++)
                for(int i=0;i<m;i++)
                    for(int j=0;j<m;j++)
                        c.a[i][j]=(c.a[i][j]+a[i][k]*b.a[k][j])%mod;
            return c;
        }
    }a,sum;
    void getne()
    {
        // int i=0,j=-1;
        // ne[0]=-1;
        // while(i<m)
        // {
            // if(c[i]==c[j]||j==-1)
                // ne[++i]=++j;
            // else
                // j=ne[j];
        // }
        for(int i=1;i<m;i++)
        {
            int j=ne[i];
            while(j&&c[i+1]!=c[j+1]) 
                j=ne[j];
            ne[i+1]=c[i+1]==c[j+1]?j+1:0;
        }   
    }
    qwe ksm(int b)
    {
        qwe r;
        r.init();
        for(int i=0;i<m;i++)
            r.a[i][i]=1;
        while(b)
        {
            if(b&1)
                r=r*a;
            a=a*a;
            b>>=1;
        }
        return r;
    }
    int main()
    {
        scanf("%d%d%d%s",&n,&m,&mod,s+1);
        for(int i=1;i<=m;i++)
            c[i]=s[i]-'0';
        getne();
        for(int i=0;i<m;i++) 
            for(int j=0;j<=9;j++)
            {
                f[i][j]=c[i+1]==j?i+1:f[ne[i]][j];
                a.a[i][f[i][j]]++;
            }
        sum.a[0][0]=1;
        sum=sum*ksm(n);
        for(int i=0;i<m;i++)
            an=(an+sum.a[0][i])%mod;
        printf("%d
    ",an);
        return 0;
    }
    
  • 相关阅读:
    Kylin 与 Spark SQL相比,有哪些差异和优势?
    apache kylin2.10在原生hadoop集群上安装
    ambari安装 QA
    mysql 5.7 学习
    Public key for ambari-server-2.4.2.0-136.x86_64.rpm is not installed 安装ambari报错总结
    python 练习
    centos 扩容
    Linux中Cache内存占用过高解决办法
    HyperLogLog
    星型模式、雪花模式和事实星座模式
  • 原文地址:https://www.cnblogs.com/lokiii/p/8604358.html
Copyright © 2011-2022 走看看