1009: [HNOI2008]GT考试

题目:传送门

题解:

   看这第一眼是不是瞬间想起组合数学???

   没错...这样想你就GG了!

   其实这是一道稍有隐藏的矩阵乘法,好题!

   首先我们可以简化一下题意:给出一个串,要求这个串不包含另一个串的方案个数

   这不是kmp吗?!(直接暴力肯定炸)

   我们可以再往DP的方面想

   f[i][j]表示长度为i的母串的后缀与子串匹配j个长度的方案数

   那么ans=Sigma(f[n][0]~f[n][m-1])

   那么我们再定义一个c[i][j]表示在子串长度为i的前缀后面加上一个数,令该前缀加上这个数所组成的新字符串与给出子串从头开始所能匹配的长度为j的方案数

   那么f[i+1][k]=f[i][j]*c[j][k]

   但是还是会炸啊!!!!!!!

   这时候怎么就想不到矩乘加速呢?!

   c数组不变,而且每次f都要乘一次,很明显可以用矩阵乘法。。。

   所以用kmp预处理矩阵就ok,但是c[i][m]不能继承,所以只能从w[i][0]继承,矩乘时就枚举0~m-1

代码:

 #include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
using namespace std;
struct matrix
{
int m[][];
matrix(){memset(m,,sizeof(m));}
}ans;
char st[];
int p[];
int n,m,mod;
matrix multi(matrix a,matrix b,int n,int m,int p)//[n,m]*[m,p];
{
matrix c;
for(int i=;i<n;i++)
for(int j=;j<p;j++)
for(int k=;k<m;k++)
c.m[i][j]=(c.m[i][j]+a.m[i][k]*b.m[k][j])%mod;
return c;
}
matrix p_m(matrix a,int b)
{
matrix sum;
for(int i=;i<m;i++)sum.m[i][i]=;
while(b)
{
if(b%==)sum=multi(sum,a,m,m,m);
a=multi(a,a,m,m,m);b/=;
}
return sum;
}
void kmp()
{
p[]=;int j;
for(int i=;i<=m;i++)
{
j=p[i-];
while(j && st[i]!=st[j+])j=p[j];
if(st[i]==st[j+])j++;
p[i]=j;
}
for(int i=;i<m;i++)
{
for(int y=;y<=;y++)
{
j=i;
while(j && st[j+]-''!=y)j=p[j];
if(st[j+]-''==y)j++;
ans.m[j][i]=(ans.m[j][i]+)%mod;
}
}
}
int main()
{
scanf("%d%d%d",&n,&m,&mod);
scanf("%s",st+);
kmp();
ans=p_m(ans,n);
int sum=;
for(int i=;i<m;i++)sum=(sum+ans.m[i][])%mod;
printf("%d\n",sum%mod);
return ;
}

bzoj1009: [HNOI2008]GT考试(kmp+矩阵乘法)的更多相关文章

  1. [bzoj1009][HNOI2008]GT考试——KMP+矩阵乘法

    Brief Description 给定一个长度为m的禁止字符串,求出长度为n的字符串的个数,满足: 这个字符串的任何一个字串都不等于给定字符串. 本题是POJ3691的弱化版本. Algorithm ...

  2. BZOJ1009: [HNOI2008]GT考试(KMP+矩阵乘法)

    Description 阿申准备报名参加GT考试,准考证号为N位数X1X2....Xn(0<=Xi<=9),他不希望准考证号上出现不吉利的数字.他的不吉利数学A1A2...Am(0< ...

  3. [bzoj1009](HNOI2008)GT考试 (kmp+矩阵快速幂加速递推)

    Description 阿 申准备报名参加GT考试,准考证号为N位数X1X2....Xn(0<=Xi<=9),他不希望准考证号上出现不吉利的数字.他的不吉利数学 A1A2...Am(0&l ...

  4. BZOJ 1009 [HNOI2008]GT考试 (KMP+矩阵乘法)

    ---恢复内容开始--- 题目大意:给定一个由数字构成的字符串A(len<=20),让你选择一个长度为n(n是给定的)字符串X,一个合法的字符串X被定义为,字符串X中不存在任何一段子串与A完全相 ...

  5. bzoj1009 [HNOI2008]GT考试——KMP+矩阵快速幂优化DP

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1009 字符串计数DP问题啊...连题解都看了好多好久才明白,别提自己想出来的蒟蒻我... 首 ...

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

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

  7. BZOJ_1009_[HNOI2008]GT考试_KMP+矩阵乘法

    BZOJ_1009_[HNOI2008]GT考试_KMP+矩阵乘法 Description 阿申准备报名参加GT考试,准考证号为N位数X1X2....Xn(0<=Xi<=9),他不希望准考 ...

  8. BZOJ 1009 [HNOI2008]GT考试 (KMP + 矩阵快速幂)

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

  9. bzoj 1009: [HNOI2008]GT考试 -- KMP+矩阵

    1009: [HNOI2008]GT考试 Time Limit: 1 Sec  Memory Limit: 162 MB Description 阿申准备报名参加GT考试,准考证号为N位数X1X2.. ...

  10. 题解:BZOJ 1009 HNOI2008 GT考试 KMP + 矩阵

    原题描述: 阿申准备报名参加GT考试,准考证号为N位数 X1X2....Xn(0<=Xi<=9),他不希望准考证号上出现不吉利的数字.他的不吉利数学A1A2...Am(0<=Ai&a ...

随机推荐

  1. 【转】 C#获取当前程序运行路径的方法集合

    [转] C#获取当前程序运行路径的方法集合 //获取当前进程的完整路径,包含文件名(进程名). string str = this.GetType().Assembly.Location; resul ...

  2. java开发必背API

    1.java.io.file类,File用于管理文件或目录: 所属套件:java.io File file = new File(fileStringPath); 1)file.mk(),真的会创建一 ...

  3. Floodlight 中创建消息对象的方法

            在 floodlight 中创建各种openflow message 和 action 等採用的是简单工厂方式.BasicFactory类(实现OFMessageFactory接口.) ...

  4. C/C++拾遗(一):关于数组的指针和数组元素首地址的一道经典题

    代码例如以下: #include <stdio.h> int main(void) { int a[5] = {1, 2, 3, 4, 5}; int *ptr = (int *)(&am ...

  5. atitit。企业组织与软件project的策略 战略 趋势 原则 attilax 大总结

    atitit. 企业组织与软件project的策略 战略 趋势 原则 attilax 大总结 1. 战略规划,适当的过度设计 1 2. 跨平台化 1 3. 可扩展性高于一切 1 4. 界面html5化 ...

  6. 【LDA】动手实现LDA

    这段时间对LDA比較感兴趣,尝试在工作中使用它.平时做想法的高速验证,都用的是"GibbsLDA++-0.2",一个c实现版本号的LDA. 这两天用c++ stl自己写了一个单机版 ...

  7. CoreData 从入门到精通 (一) 数据模型 + CoreData 栈的创建

    CoreData 是 Cocoa 平台上用来管理模型层数据和数据持久化的一个框架,说简单点,就是一个数据库存储框架.CoreData 里相关的概念比较多,而且初始化也非常繁琐,所以对初学者的学习还是有 ...

  8. BZOJ 1101 莫比乌斯函数+分块

    思路: 题目中的gcd(x,y)=d (x<=a,y<=b)可以转化成 求:gcd(x,y)=1 (1<=x<=a/d 1<=y<=b/d) 设 G(x,y)表示x ...

  9. Ubuntu下gcc安装

    在Ubuntu下安装GCC和其他一些Linux系统有点不一样. 方法一: 该方法超简单:sudo apt-get  build-depgcc 就上面这条命令就可以搞定 方法二:sudo apt-get ...

  10. Windbg调试托管代码

    Windbg调试.net托管代码需要借助于SOS.dll,.Net 4.0的32位sos.dll的路径在C:\Windows\Microsoft.NET\Framework\v4.0.30319,64 ...