• 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;
    }
  • 相关阅读:
    iptables的例子1
    Nginx教程
    bash编程基础
    centos7 PXE自动安装环境搭建
    矛盾破裂了
    20200823-矩阵的收尾与离散控制的跌跌撞撞
    20200817-三大公式的结束-频域法的再探
    markdown换行
    由二〇二〇新冠疫情引发的对于开源、分享这一理念的看法
    Windows简单使用记录
  • 原文地址:https://www.cnblogs.com/IUUUUUUUskyyy/p/7029290.html
Copyright © 2020-2023  润新知