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取余的结果.

Sample Input

4 3 100
111

Sample Output

81

Solution

好题。不看题解不会写题系列。
虽然AC自动机的题解本来就没几篇我还一篇都没看懂
一开始口胡的写法是对的不过因为一个小瑕疵写挂了
建议先写过BZOJ1030文本生成器再来写这个题
不然这个题解可能看不懂
而且因为我比较菜不会的东西太多所以这个题解可能很长……
 
考虑暴力,我们会发现这个题和我做过的BZOJ1030好像几乎一模一样……
就连DP式子都一样
只不过N太大了没法转移是么……
贴一段文本生成器的AC代码。
for (int i=1;i<=m;++i)
    for (int j=0;j<=sz;++j)
        for (int k=0;k<26;++k)
            if (!End[Son[j][k]])
                (f[i][Son[j][k]]+=f[i-1][j])%=MOD;
我们发现外层的m(也就是本题的N)循环的时候,里面两个循环每次进行的转移都是机械一样的。
都是根据父亲的状态来推儿子的状态。
这样的话,我们就可以用矩阵快速幂来优化了。

举个例子
4 3 100
111
这是样例。
我们将初始矩阵start定义为[1,0,0],这对应的是文本生成器一题中的初始化f[0][0]=1;
然后将x节点与x的所有儿子节点在转移矩阵a中a[x][son]+=1
这样在矩乘转移的时候我们就可以把父亲的状态推到儿子了
最后答案即为start*a^n

因为很容易发现,start是f[0][]的所有状态
start*a是f[1][]的所有状态
那么start*a^n即为f[n][]的所有状态
将start*a^n矩阵里的所有数值加起来即为所求答案。
orz感觉自己已经是一条咸鱼了

对了送组数据:
1000000000 19 9973
1010100110011000001
5753

Code

 #include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#define N (10005)
using namespace std; int Son[N][],End[N],Fail[N];
int n,m,sz,MOD;
char s[N];
queue<int>q; struct Matrix
{
int m[][];
void clear(){memset(m,,sizeof(m));};
}; Matrix operator * (Matrix a,Matrix b)
{
Matrix ans; ans.clear();
for (int i=; i<=sz+; ++i)
for (int j=; j<=sz+; ++j)
for (int k=; k<=sz+; ++k)
(ans.m[i][j]+=a.m[i][k]*b.m[k][j])%=MOD;
return ans;
} Matrix Qpow(Matrix a,int p)
{
Matrix ans; ans.clear();
for (int i=; i<=sz+; ++i) ans.m[i][i]=;
while (p)
{
if (p&) ans=ans*a;
a=a*a; p>>=;
}
return ans;
} void Insert(char s[])
{
int now=,len=strlen(s);
for (int i=; i<len; ++i)
{
int x=s[i]-'';
if (!Son[now][x]) Son[now][x]=++sz;
now=Son[now][x];
}
End[now]|=;
} void Build_Fail()
{
for (int i=; i<; ++i)
if (Son[][i])
q.push(Son[][i]);
while (!q.empty())
{
int now=q.front();
q.pop();
for (int i=; i<; ++i)
{
if (!Son[now][i])
{
Son[now][i]=Son[Fail[now]][i];
continue;
}
End[Son[now][i]]|=End[Son[Fail[now]][i]];
Fail[Son[now][i]]=Son[Fail[now]][i];
q.push(Son[now][i]);
}
}
} int main()
{
Matrix a; a.clear();
Matrix start; start.clear();
start.m[][]=; scanf("%d%d%d",&n,&m,&MOD);
scanf("%s",s),Insert(s);
Build_Fail();
for (int i=;i<=sz;++i)
for (int j=;j<;++j)
if (!End[Son[i][j]])
a.m[i+][Son[i][j]+]++;
a=Qpow(a,n);
a=start*a;
int ans=;
for (int i=;i<=sz+;++i)
(ans+=a.m[][i])%=MOD;
printf("%d",ans);
}

BZOJ1009:[HNOI2008]GT考试(AC自动机,矩乘DP)的更多相关文章

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

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

  2. BZOJ1009: [HNOI2008]GT考试 矩阵快速幂+kmp+dp

    这个题你发现打暴力的话可以记忆化搜素加剪枝,那么意味着可以递推,我们搜的话就是1010^9我们就往下匹配遇到匹配成功就return,那么我们可以想一下什么决定了状态,我们考虑kmp的过程,对于我们目前 ...

  3. [BZOJ1009] [HNOI2008] GT考试(KMP+dp+矩阵快速幂)

    [BZOJ1009] [HNOI2008] GT考试(KMP+dp+矩阵快速幂) 题面 阿申准备报名参加GT考试,准考证号为N位数X1X2-.Xn,他不希望准考证号上出现不吉利的数字.他的不吉利数学A ...

  4. hdu 4057--Rescue the Rabbit(AC自动机+状压DP)

    题目链接 Problem Description Dr. X is a biologist, who likes rabbits very much and can do everything for ...

  5. hdu 2825 aC自动机+状压dp

    Wireless Password Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others ...

  6. [Bzoj1009][HNOI2008]GT考试(KMP)(矩乘优化DP)

    1009: [HNOI2008]GT考试 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 4309  Solved: 2640[Submit][Statu ...

  7. BZOJ1009 [HNOI2008]GT考试 矩阵

    去博客园看该题解 题目 [bzoj1009][HNOI2008]GT考试 Description 阿申准备报名参加GT考试,准考证号为N位数X1X2….Xn(0<=Xi<=9),他不希望准 ...

  8. 【bzoj1009】: [HNOI2008]GT考试 字符串-kmp-矩阵乘法-DP

    [bzoj1009]: [HNOI2008]GT考试 先用kmp写个暴力 /* http://www.cnblogs.com/karl07/ */ #include <cstdlib> # ...

  9. bzoj1009: [HNOI2008]GT考试(kmp+矩阵乘法)

    1009: [HNOI2008]GT考试 题目:传送门 题解: 看这第一眼是不是瞬间想起组合数学??? 没错...这样想你就GG了! 其实这是一道稍有隐藏的矩阵乘法,好题! 首先我们可以简化一下题意: ...

随机推荐

  1. [转]JavaScript和html5 canvas生成圆形印章

    本文转自:http://www.cnblogs.com/dragondean/p/6013529.html 代码: function createSeal(id,company,name){ var ...

  2. The Struts dispatcher cannot be found. This is usually caused by using Struts tags without the associated filter.

    The Struts dispatcher cannot be found. This is usually caused by using Struts tags without the assoc ...

  3. bnu Game 博弈。

    Game Time Limit: 10000ms Case Time Limit: 10000ms Memory Limit: 65536KB   64-bit integer IO format:  ...

  4. thinkphp注册并写入数据到数据库中

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  5. String Control

    using System; using System.Collections.Generic; using System.Text; using System.Web; using System.We ...

  6. webservice使用windows身份验证,ajax请求报错401未授权的解决办法

    $.ajax({ type: "GET", url: service_url, dataType: "xml", data: "ParamId=&qu ...

  7. [小北De编程手记] : Lesson 05 - Selenium For C# 之 API 下

    上一篇,我们介绍了一些Selenium WebDriver相关的API,下面我们就接着上一篇继续介绍Selenium常用的API,这一篇的内容主要涉及到以下话题: Selenium API:复杂事件处 ...

  8. 万网知您所需,“域”众不同--.link/.love/.help等一大波新顶级域来袭!

    万网在新顶级域市场再次发力,一大波域名界的小鲜肉新鲜上线,价格优惠,限时低至9元起,更有丰富的可注册资源. 一下,即刻世界,用记录生活,用观看世界, 用和做最好的! 新上线的个性化新顶级域价格如下: ...

  9. Oracle数据库中设置表字段为自动序列

    --创建序列 increment ; --创建触发器 create or replace trigger zonecode_trigger before insert on org_HospitalZ ...

  10. CRM系统知识点之一权限(RBAC)

    一个项目可以有多个应用 一个做成组件 一个做逻辑判断一个应用(做成组件形式)可以服务于多个项目 rbac权限(role-base access control)who what how什么样的角色对什 ...