题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1009

题意:给定一个长度为m的串s。有多少种长度为n的串不包含s?

思路:(1)将s插入trie建立ac自动机。(2)以自动机中的状态作为节点,建立矩阵A[i][j],A[i][j]=1表示j节点为合法状态,也就是能向j转移。(3)计算ans=A^n,则ans=sum(ans[0][i])。

struct node
{
    int next[10],fail,flag;
 
    void init()
    {
        clr(next,0);
        fail=-1;
        flag=0;
    }
};
 
node a[N];
int e,n,m,K;
char s[N];

void insert(char s[])
{
    int i,k,p=0;
    for(i=0;s[i];i++)
    {
        k=s[i]-'0';
        if(a[p].next[k]==0)
        {
            a[e].init();
            a[p].next[k]=e++;
        }
        p=a[p].next[k];
    }
    a[p].flag=1;
}
 
queue<int> Q;
 
void build()
{
    Q.push(0);
    int i,j,k,p,q;
    while(!Q.empty())
    {
        k=Q.front();
        Q.pop();
        for(i=0;i<10;i++)
        {
            if(a[k].next[i])
            {
                p=a[k].next[i];
                q=a[k].fail;
                while(q!=-1&&!a[q].next[i]) q=a[q].fail;
                if(q==-1) a[p].fail=0;
                else
                {
                    a[p].fail=a[q].next[i];
                    a[p].flag|=a[a[p].fail].flag;
                }
                Q.push(p);
            }
            else
            {
                q=a[k].fail;
                while(q!=-1&&!a[q].next[i]) q=a[q].fail;
                if(q==-1) a[k].next[i]=0;
                else a[k].next[i]=a[q].next[i];
            }
        }
    }
}

class Matrix
{
public:
    u64 a[N][N];
 
    void init(int x)
    {
        clr(a,0);
        int i;
        if(x==1)
        {
            FOR0(i,e) a[i][i]=1;
        }
    }
 
    Matrix operator*(Matrix a)
    {
        Matrix ans,p=*this;
        ans.init(0);
        int i,j,k;
        FOR0(k,e) FOR0(i,e) FOR0(j,e)
        {
            ans.a[i][j]+=p.a[i][k]*a.a[k][j];
            ans.a[i][j]%=K;
        }
        return ans;
    }
 
    Matrix Pow(int n)
    {
        Matrix ans,p=*this;
        ans.init(1);
        while(n)
        {
            if(n&1) ans=ans*p;
            p=p*p;
            n>>=1;
        }
        return ans;
    }
};
 
Matrix p;
 
int main()
{
    scanf("%d%d%d",&n,&m,&K);
    a[0].init();e=1;
    RD(s),insert(s);
    int i,j,k;
    build(); p.init(0);
    FOR0(i,e) if(!a[i].flag) FOR0(j,10)
    {
        k=a[i].next[j];
        if(!a[k].flag) p.a[i][k]++;
    }
    p=p.Pow(n);
    u64 ans=0;
    FOR0(i,e) ans=(ans+p.a[0][i])%K;
    PR(ans);
    return 0;
}

BZOJ 1009 GT考试(ac自动机+矩阵DP)的更多相关文章

  1. BZOJ 1009 GT考试 (AC自动机 + 矩阵乘法加速dp)

    题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=1009 题意: 准考证号为\(n\)位数\(X_1X_2....X_n(0<=X_ ...

  2. bzoj 2553: [BeiJing2011]禁忌 AC自动机+矩阵乘法

    题目大意: http://www.lydsy.com/JudgeOnline/problem.php?id=2553 题解: 利用AC自动机的dp求出所有的转移 然后将所有的转移储存到矩阵中,进行矩阵 ...

  3. POJ2778&HDU2243&POJ1625(AC自动机+矩阵/DP)

    POJ2778 题意:只有四种字符的字符串(A, C, T and G),有M中字符串不能出现,为长度为n的字符串可以有多少种. 题解:在字符串上有L中状态,所以就有L*A(字符个数)中状态转移.这里 ...

  4. bzoj 2553 [BeiJing2011]禁忌——AC自动机+概率DP+矩阵

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2553 看了题解才会…… 首先,给定一个串,最好的划分方式是按禁忌串出现的右端点排序,遇到能填 ...

  5. bzoj1009: [HNOI2008]GT考试 ac自动机+矩阵快速幂

    https://www.lydsy.com/JudgeOnline/problem.php?id=1009 阿申准备报名参加GT考试,准考证号为N位数X1X2....Xn(0<=Xi<=9 ...

  6. BZOJ 1559: [JSOI2009]密码( AC自动机 + 状压dp )

    建AC自动机后, dp(x, y, s)表示当前长度为x, 在结点y, 包括的串的状态为s的方案数, 转移就在自动机上走就行了. 对于输出方案, 必定是由给出的串组成(因为<=42), 所以直接 ...

  7. BZOJ 3530 [SDOI2014]数数 (Trie图/AC自动机+数位DP)

    题目大意:略 裸的AC自动机+数位DP吧... 定义f[i][x][0/1]表示已经匹配到了第i位,当前位置是x,0表示没到上限,1到上限,此时数是数量 然而会出现虚拟前导零,即前几位没有数字的情况, ...

  8. 关于AC自动机和DP的联系

    首先是描述个大概.不说一些特殊的DP 或者借用矩阵来状态转移 (这些本质都是一样的). 只讲AC自动机和DP的关系(个人理解). AC自动机 又可以叫做状态机. 我一开始的认为.AC 自动机提供了一些 ...

  9. Censored! POJ - 1625 AC自动机+大数DP

    题意: 给出一n种字符的字典,有p个禁用的单词, 问能组成多少个不同的长度为m的合法字符串.(m<=50) 题解: 是不是个我们之前做的题目非常非常像,题意都一样. 直接将上次写的AC自动机+矩 ...

随机推荐

  1. hdu 4003 Find Metal Mineral 树形DP

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4003 Humans have discovered a kind of new metal miner ...

  2. max_flow(Dinic) 分类: ACM TYPE 2014-09-02 15:42 94人阅读 评论(0) 收藏

    #include <cstdio> #include <iostream> #include <cstring> #include<queue> #in ...

  3. [百度空间] [原]跨平台编程注意事项(二): windows下 x86到x64的移植

    之前转的: 将程序移植到64位Windows 还有自己乱写的一篇: 跨平台编程注意事项(一) 之前对于x64平台的移植都是纸上谈兵,算是前期准备工作, 但起码在写代码时,已经非常注意了.所以现在移植起 ...

  4. jQuery1.9.1--结构及$方法的工作原理源码分析

    jQuery的$方法使用起来非常的多样式,接口实在太灵活了,有点违反设计模式的原则职责单一.但是用户却非常喜欢这种方式,因为不用记那么多名称,我只要记住一个$就可以实现许多功能,这个$简直就像个万能的 ...

  5. win7修改hosts文件方法

    因权限的关系,导致无法修改,解决如下: hosts属性 --> 安全 --> 编辑权限 --> 完全控制,就可以修改该文件了.win7默认不能修改hosts文件.

  6. Linux关于watch的用法

    Linux关于watch的用法 2011-07-20      0个评论       收藏    我要投稿 watch 是一个非常实用的命令,基本所有的 Linux 发行版都带有这个小工具,如同名字一 ...

  7. acdream1116 Gao the string!(扩展KMP)

    今天是字符串填坑的一天,首先填的第一个坑是扩展KMP.总结一下KMP和扩展KMP的区别. 在这里s是主串,t是模式串. KMP可以求出的是以s[i]为结尾的串和 t前缀匹配的最长的长度.假如这个长度是 ...

  8. FZU2165 v11(带权的重复覆盖)

    题意:有n个boss,m种武器,每种武器选用的时候需要有一定的花费ci,然后这个武器可以消灭掉其中一些BOSS,问你消灭完所有的BOSS,需要的最少花费是多少. 当时比赛的时候,看到这题以为是什么网络 ...

  9. iOS正则匹配手机号

    #pragma 正则匹配手机号 + (BOOL)validateMobile:(NSString *)mobileNum {     /**      * 手机号码      * 移动:134[0-8 ...

  10. Android线程消息通信(二)

    创建线程消息队列 Android应用程序的消息队列是使用一个MessageQueue对象来描述的,它可以通过调用Looper类的静态成员函数prepareMainLooper或者prepare来创建, ...