zoukankan      html  css  js  c++  java
  • AC日记——[HNOI2008]GT考试 bzoj 1009

    1009

    思路:

      KMP上走DP(矩阵加速);

      DP[i][j]表示当前在第i位,同是匹配到不吉利串的第j位的方案数;

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    int mod;
    struct MatrixType {
        int n,m,ai[40][40];
        void mem(int n_,int m_)
        {
            n=n_,m=m_;
            for(int i=0;i<=n;i++)
            {
                for(int v=0;v<=m;v++) ai[i][v]=0;
            }
        }
        MatrixType operator*(const MatrixType pos)const
        {
            MatrixType res;
            res.mem(n,pos.m);
            for(int i=0;i<=res.n;i++)
            {
                for(int k=0;k<=res.m;k++)
                {
                    for(int v=0;v<=m;v++) res.ai[i][k]=(res.ai[i][k]+(ai[i][v]*pos.ai[v][k])%mod)%mod;
                }
            }
            return res;
        }
        void debug()
        {
            puts("");
            for(int i=0;i<=n;i++)
            {
                for(int v=0;v<=m;v++) printf("%d ",ai[i][v]);
                putchar('
    ');
            }
            puts("");
        }
    };
    int n,m,ti[1001],Next[1001],last[1001],to[40][40];
    void poww(MatrixType res,MatrixType pos,int mi)
    {
        while(mi)
        {
            if(mi&1) res=res*pos;
            mi=mi>>1,pos=pos*pos;
        }
        long long ans=0;
        for(int i=0;i<m;i++) ans=(ans+res.ai[0][i])%mod;
        cout<<ans;
    }
    int main()
    {
        freopen("data.txt","r",stdin);
        scanf("%d%d%d",&n,&m,&mod);
        char ch[30];scanf("%s",ch+1);
        for(int i=1;i<=m;i++) ti[i]=ch[i]-'0';
        for(int i=1;i<m;i++)
        {
            int v=Next[i];
            while(v&&ti[i+1]!=ti[v+1]) v=Next[v];
            Next[i+1]=ti[i+1]==ti[v+1]?v+1:0;
        }
        for(int i=0;i<m;i++)
        {
            for(int v=0;v<=9;v++)
            {
                to[i][v]=ti[i+1]==v?i+1:to[Next[i]][v];
            }
        }
        MatrixType sta,tmp;
        sta.mem(0,m-1),sta.ai[0][0]=1;
        tmp.mem(m-1,m-1);
        for(int i=0;i<m;i++)
        {
            for(int v=0;v<=9;v++)
            {
                if(to[i][v]!=m) tmp.ai[i][to[i][v]]++;
            }
        }
        poww(sta,tmp,n);
        return 0;
    }
  • 相关阅读:
    动态规划训练之十
    数据结构训练之一
    图论训练之八
    数论训练之三
    动态规划训练之九
    动态规划训练之八
    动态规划训练之七
    杂题训练之三
    图论训练之七
    动态规划训练之六
  • 原文地址:https://www.cnblogs.com/IUUUUUUUskyyy/p/7029290.html
Copyright © 2011-2022 走看看