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. viewport其实没那么难理解

    在学习移动端布局的时候,你肯定听说过"viewport"这个词,然后去问度娘或谷歌.你会惊奇的发现,这个viewport不简单,居然有那么多兄弟——layout viewport. ...

  2. tomcat绑定域名绑定端口及更换ROOT目录

    一.更换ROOT目录 tomcat默认网站目录为 webapps/ROOT ,那么我们如何改为自己的网站目录呢? 1.打开并编辑tomcat目录下的 conf/server.xml 大约在148行的位 ...

  3. TortoiseGit记住用户名&密码

    配置并安装好git之后鼠标右键: 在全局配置文件末尾添加一行: [credential] helper = store *主意保存时以utf-8格式保存,否则中文可能会乱码,这样下次只需输入一次用户名 ...

  4. [android] 界面的划分

    1.统一界面管理 1.1利用一个activity去管理应用的所有的界面 1.1.1 理解Activity,Window和View之间的关系 1.1.2 避免Activity过多导致的问题, 例如:彻底 ...

  5. MySQL:ERROR 1820 (HY000): You must reset your password using ALTER USER statement before executing this statement.

    解决方法: 修改密码:alter user 'root'@'localhost' identified by '123456'; mysql> use mysql; ERROR 1820 (HY ...

  6. mybatis向数据库插入数据 (传入的是一个实体类)

    /** * 插入用户信息 user为实体类 * @param user */ public int insert( User user); //实体类不用@param标注 //mybatis的xml文 ...

  7. 00HTML

    一.概述 超文本标记语言(Hyper Text Markup Language),HTML是一门描述性的语言.基本语法: <标签> 内容 </标签>** 在一个网页中,HTML ...

  8. layui-学习02-全局样式

    CSS内置公共基础类 类名(class) 说明 布局 layui-main 用于设置一个宽度为 1140px 的水平居中块(无响应式) layui-inline 用于将标签设为内联块状元素 layui ...

  9. JSTL数据格式化

    日期表示 <fmt:formatDate value="${DATE1}" pattern="yyyy-MM-dd hh:mm:ss" type=&quo ...

  10. eclipse插件开发常见的问题及解决办法

    莫名其妙地我的某个Plug-in Projects出现了这样的Error:An API baseline has not been set for the current workspace.虽然后来 ...