【BZOJ1009】【HNOI2008】GT考试 AC自动机+矩阵乘法

广告:

#include <stdio.h>
int main()
{
    puts("转载请注明出处[vmurder]谢谢");
    puts("网址:blog.csdn.net/vmurder/article/details/44003109");
}

题解:

建立AC自动机的过程可以改为KMP。

反正单串233。

代码:

#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define T 21
using namespace std;
int n,m,p;
struct MRX
{
    int x[T][T];
}Ini,Std,Trs,E;
MRX operator * (const MRX &A,const MRX &B)
{
    MRX C=E;
    int i,j,k;
    for(i=0;i<T;i++)for(j=0;j<T;j++)for(k=0;k<T;k++)
        (C.x[i][j]+=(long long)A.x[i][k]*B.x[k][j]%p)%=p;
    return C;
}

MRX power(MRX X,int p)
{
    MRX Ans=Std;
    while(p)
    {
        if(p&1)Ans=Ans*X;
        X=X*X,p>>=1;
    }
    return Ans;
}
struct ACAUTO
{
    int son[T][T],cnt;
    char src[T];
    void build_Trie()
    {
        scanf("%s",src);
        int i,x=0,alp;
        for(i=0;src[i];i++)
        {
            alp=src[i]-‘0‘;
            if(!son[x][alp])son[x][alp]=++cnt;
            x=son[x][alp];
        }
    }
    queue<int>q;
    int fail[T];
    void build_Fail()
    {
        while(!q.empty())q.pop();

        q.push(1);
        int i,u,v;
        while(!q.empty())
        {
            u=q.front(),q.pop();
            for(i=0;i<10;i++)
            {
                if(v=son[u][i])
                {
                    if(u)fail[v]=son[fail[u]][i];
                    else fail[v]=1;
                    q.push(v);
                }
                else son[u][i]=son[fail[u]][i];
            }
        }
    }
    void build_Mrx()
    {
        int i,j,k;
        for(i=0;i<cnt;i++)for(j=0;j<10;j++)
            Trs.x[son[i][j]][i]++;
    }

}acauto;
int main()
{
    freopen("test.in","r",stdin);
    scanf("%d%d%d",&n,&m,&p);

    acauto.build_Trie();
    acauto.build_Fail();
    acauto.build_Mrx();

    for(int i=0;i<T;i++)Std.x[i][i]=1;
    Ini.x[0][0]=1;
    MRX Temp=power(Trs,n);
    Temp=Temp*Ini;
    int ans=0;
    for(int i=0;i<m;i++)ans=(ans+Temp.x[i][0])%p;
    printf("%d\n",ans);

/*  MRX ToT=Ini;
    for(int i=1;i<=n;i++)
        ToT=Trs*ToT;
*/
    return 0;
}
时间: 2024-12-28 01:10:41

【BZOJ1009】【HNOI2008】GT考试 AC自动机+矩阵乘法的相关文章

BZOJ 1009 [HNOI2008]GT考试 AC自动机+矩阵乘法

题意:链接略 方法: AC自动机+矩阵乘法 解析: 和POJ 2778 一样的题. 大概的思路就是我们建AC自动机的时候需要注意如果某个点是一个串的结尾的话,那么下面的节点都要看成结尾节点. 然后按照AC自动机赋一下矩阵内部值就好了. 赋的矩阵代表从一个节点走一步走到另一个节点有多少方案. 然后经典模型,矩阵的n次方即可. 代码: #include <queue> #include <cstdio> #include <cstring> #include <ios

BZOJ 1009: [HNOI2008]GT考试 AC自动机+矩阵快速幂

经典题目了....虽然只有一个不能出现的字符串,但还是写了ac自动机 1009: [HNOI2008]GT考试 Time Limit: 1 Sec  Memory Limit: 162 MB Submit: 2051  Solved: 1257 [Submit][Status][Discuss] Description 阿申准备报名参加GT考试,准考证号为N位数X1X2....Xn(0<=Xi<=9),他不希望准考证号上出现不吉利的数字.他的不吉利数学A1A2...Am(0<=Ai<

[BZOJ1009] [HNOI2008] GT考试 (KMP &amp; dp &amp; 矩阵乘法)

Description 阿申准备报名参加GT考试,准考证号为N位数X1X2....Xn(0<=Xi<=9),他不希望准考证号上出现不吉利的数字. 他的不吉利数学A1A2...Am(0<=Ai<=9)有M位,不出现是指X1X2...Xn中没有恰好一段等于A1A2...Am. A1和X1可以为0 Input 第一行输入N,M,K.接下来一行输入M位的数. N<=10^9,M<=20,K<=1000 Output 阿申想知道不出现不吉利数字的号码有多少种,输出模K取余的

BZOJ1009 HNOI2008 GT考试 一般DP+矩阵乘法+KMP

题意:给定一个长度为M的字符串A,求长度为N的字符串中,子串中不包含A的字符串的数量,其中字符串仅由‘0’-‘9’组成. 题解:设f[i][j]=长度为i最后几位能匹配A的前j个字符的字符串种数,那么每往后添加一个字符,能转移到的位置通过KMP的Next数组很轻松就能找到.那么我们就能构造出来一个矩阵,a[i][j]=1表示可以通过在A[i]后面加一个字符,使得A[1]-A[j]成为原有字符串的子串.快速幂优化后答案就是f[N][0]+……+f[N][M-1] #include <cstdio>

poj2778DNA Sequence(AC自动机+矩阵乘法)

链接 看此题前先看一下matrix67大神写的关于十个矩阵的题目中的一个,如下: 经典题目8 给定一个有向图,问从A点恰好走k步(允许重复经过边)到达B点的方案数mod p的值    把给定的图转为邻接矩阵,即A(i,j)=1当且仅当存在一条边i->j.令C=A*A,那么C(i,j)=ΣA(i,k)*A(k,j),实际上就等于从点i到点j恰好经过2条边的路径数(枚举k为中转点).类似地,C*A的第i行第j列就表示从i到j经过3条边的路径数.同理,如果要求经过k步的路径数,我们只需要二分求出A^k

[BZOJ 1009] [HNOI2008] GT考试 【AC自动机 + 矩阵乘法优化DP】

题目链接:BZOJ - 1009 题目分析 题目要求求出不包含给定字符串的长度为 n 的字符串的数量. 既然这样,应该就是 KMP + DP ,用 f[i][j] 表示长度为 i ,匹配到模式串第 j 位的字符串个数,然后转移就是可以从第 j 位加上一个字符转移到另一个位置. 然而..我并没有写过KMP + DP,我觉得还是写AC自动机+DP比较简单..于是,尽管只有一个模式串,我还是写了AC自动机+DP. 然后就是建出AC自动机,f[i][j] 表示长度为 i ,走到节点 j 的字符串的个数.

【BZOJ1009】[HNOI2008]GT考试 next数组+矩阵乘法

[BZOJ1009][HNOI2008]GT考试 Description 阿申准备报名参加GT考试,准考证号为N位数X1X2....Xn(0<=Xi<=9),他不希望准考证号上出现不吉利的数字.他的不吉利数学A1A2...Am(0<=Ai<=9)有M位,不出现是指X1X2...Xn中没有恰好一段等于A1A2...Am. A1和X1可以为0 Input 第一行输入N,M,K.接下来一行输入M位的数. N<=10^9,M<=20,K<=1000 Output 阿申想知

POJ 2778 DNA Sequence (AC自动机,矩阵乘法)

题意:给定n个不能出现的模式串,给定一个长度m,要求长度为m的合法串有多少种. 思路:用AC自动机,利用AC自动机上的节点做矩阵乘法. 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cmath> 5 #include<string> 6 #include<algorithm> 7 #include<queue> 8 #defin

【BZOJ-1009】GT考试 KMP+DP+矩阵乘法+快速幂

1009: [HNOI2008]GT考试 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 2745  Solved: 1694[Submit][Status][Discuss] Description 阿申准备报名参加GT考试,准考证号为N位数X1X2....Xn(0<=Xi<=9),他不希望准考证号上出现不吉利的数字.他的不吉利数学A1A2...Am(0<=Ai<=9)有M位,不出现是指X1X2...Xn中没有恰好一段等于A1A2..