zoukankan      html  css  js  c++  java
  • bzoj1009

    一看还以为要搞一个类似于数位dp的东西,然后还想不出来,一点没往别处想还是我太弱了。。。

    我们把这题的过程看成字符串的匹配,那就是求匹配到最后还没匹配上的情况有多少种,我们可以考虑kmp的过程来dp计数;

    dp[i][j]=sum(dp[i-1][k]*cnt[k][j])(j,k<m),dp[i][j]表示到了s串的第i个字符和t串匹配了j个的情况,cnt[k][j]表示由原来匹配了k个后移一个字符之后变成j个的情况数,可以由kmp数组预处理出来,我们可以把cnt数组看成一个矩阵CNT,把每个dp[i]看成一个矩阵DPi,则

    DPn=DPn-1*CNT;

    DPn=DP0*CNT^n;

    矩阵快速幂

    #include<iostream>
    #include<cstring>
    #include<cmath>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    int n,m,mod;
    struct matr{
        int t[25][25];
        matr operator*(matr &a){
            matr c;
            for(int i=0;i<m;++i)
                for(int j=0;j<m;++j){
                    c.t[i][j]=0;
                    for(int k=0;k<m;++k)
                    c.t[i][j]=(c.t[i][j]+t[i][k]*a.t[k][j]%mod)%mod;
                }
            return c;
        }
    }A,ans;
    char s[25];
    int ne[25];
    void pre(){
        for(int i=2,j=0;i<=m;++i){
            while(s[j+1]!=s[i]&&j>0)j=ne[j];
            if(s[j+1]==s[i])++j;ne[i]=j;
        }
    }
    int main(){
        cin>>n>>m>>mod;
        scanf("%s",s+1);
        pre();
        for(int i=0;i<m;++i)
          for(int j=0;j<=9;++j){
            int p=i;
            while(p>0&&s[p+1]-'0'!=j)p=ne[p];
            if(s[p+1]-'0'==j)++p;
            if(p!=m)A.t[i][p]=(A.t[i][p]+1)%mod;
        }
        for(int i=0;i<m;++i)ans.t[i][i]=1;
        while(n){
            if(n&1)ans=ans*A;
            n>>=1;A=A*A;
        }
        int sum=0;
        for(int i=0;i<m;++i)
        sum=(sum+ans.t[0][i])%mod;
        cout<<sum<<endl;
        system("pause");
        return 0;
    }
  • 相关阅读:
    【转贴】Render to Texture(渲染到纹理)
    【转贴】EffectFramework
    真正的电脑高手
    【ZT】剑道与编程之道
    【转贴】DXUT 框架入门 2
    【转贴】DXUT 框架函数介绍
    第四章 治病法要(1)
    第一章 略说中医的学习与研究(5)
    第二章 伤寒之意义(2)
    第一章 略说中医的学习与研究(4)
  • 原文地址:https://www.cnblogs.com/dibaotianxing/p/8302136.html
Copyright © 2011-2022 走看看