zoukankan      html  css  js  c++  java
  • BZOJ 1009 [HNOI2008]GT考试

    设dp[i][j]为当前是第i位考号、现在匹配到A的第j位的方案数

    因为假如当前匹配j位,如果选择的下一位与A[j+1]不同,新的匹配位数是num(fail[j])而不是0

    设由匹配j位转移到匹配k位的方案数为c[j][k]那么

    $dp[i][j] = sum f[i-1][k]*c[k][j] $


    这个式子是线性的,计算出t矩阵的n次幂,乘以初始矩阵
    c矩阵枚举当前匹配多少位,利用KMP计算c矩阵

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    const int maxn = 33;
    int n,m,k,T[maxn],next[maxn];
    struct Matrix {
        int f[maxn][maxn];
        Matrix () { memset(f,0,sizeof f);};
        void clear() { memset(f,0,sizeof f);};
    }a,F;
    Matrix operator * (const Matrix & a,const Matrix & b) {
        Matrix ret;
        for(int i=0;i<m;++i)
            for(int j=0;j<m;++j)
                for(int kk=0;kk<m;++kk) 
                    ret.f[i][j]=(ret.f[i][j]+a.f[i][kk]*b.f[kk][j])%k;
        return ret;
    }
    void get_next() {
        next[1]=0;
        for(int j=0,i=2;i<=m;++i) {
            for(;j && T[j+1] != T[i];j=next[j]);
            if(T[j+1]==T[i]) ++j; next[i]=j;
        }
    }
    void get_a() {
        for(int i=0;i<m;++i) 
            for(int k,j=0;j<10;++j) {
                for(k=i; k && T[k+1]!=j; k=next[k]);
                if(T[k+1]==j) ++k;
                a.f[i][k]++;
            }
    }
    void pow() {
        Matrix tmp=a;
        a.clear();
        for(int i=0;i<m;++i) a.f[i][i]=1;
        for(;n;n>>=1,tmp=tmp*tmp) if(n&1) a=a*tmp;
    }
    int main() {
        char c[maxn];
        scanf("%d%d%d%s",&n,&m,&k,c+1);
        for(int i=1;i<=m;++i) T[i]=c[i]-'0';
        get_next();get_a();pow();
        int Ans=0;
        F.f[0][0]=1;
        F=F*a;
        for(int i=0;i<m;++i) Ans=(Ans+F.f[0][i])%k;
        printf("%d
    ",Ans);
    }
  • 相关阅读:
    Linux文件系统
    Ant整合svnant(三)
    Linux文件系统基本结构和基本操作管理
    Ant生成javadoc(四)
    Linux系统常用命令
    Linux系统目录架构
    使用fdisk进行磁盘管理
    命令行BASH的基本操作
    python 获取项目的根路径
    游戏自动化测试思路
  • 原文地址:https://www.cnblogs.com/sssy/p/8612815.html
Copyright © 2011-2022 走看看