1009: [HNOI2008]GT考试

Time Limit: 1 Sec  Memory Limit: 162 MB
Submit: 4723  Solved: 2940
[Submit][Status][Discuss]

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

HINT

 

Source

     
 
    一个容易想到的转移方程是f[i][j]表示当前学号长度为i,在状态j时的方案个数,它可以推出的状态就是->f[i+1][k],下一步可以选择的数字[0,9],根据失配指针寻找应该转移到的状态k就好了,就是AC自动机,只不过是单链的为了方便用kmp处理。显然所有的f[i+1][]状态都来自于
f[i][],于是想到利用转移矩阵A,实现 (f[i][0],f[i][1],,,f[i][m])*A=(f[i+1][0],f[i+1][1],,,,f[i+1][m]),矩阵A[i][j]表示f[i+1][j]+=A[i][j]*f[i][j].
 #include<iostream>
#include<cstring>
#include<queue>
#include<cstdio>
#include<stack>
#include<set>
#include<map>
#include<cmath>
#include<ctime>
#include<time.h>
#include<algorithm>
#include<bits/stdc++.h>
using namespace std;
#define mp make_pair
#define pb push_back
#define debug puts("debug")
#define LL long long
#define pii pair<int,int>
#define eps 1e-10
#define inf 0x3f3f3f3f LL N,M,K;
int f[];
char s[];
struct matrix{
LL len;
LL a[][];
matrix(){
memset(a,,sizeof(a));
}
matrix& operator*(matrix& tmp){
matrix ans;
ans.len=len;
for(int i=;i<=len;++i){
for(int j=;j<=len;++j){
for(int k=;k<=len;++k){
ans.a[i][k]+=a[i][j]*tmp.a[j][k];
ans.a[i][k]%=K;
}
}
}
return ans;
} }A,I;
matrix qpow(matrix X,int n){
matrix ans=I;
while(n){
if(n&) ans=ans*X;
X=X*X;
n>>=;
}
return ans;
}
void init(){
int i,j,k,len;
I.len=A.len=M;
for(i=;i<=M;++i)I.a[i][i]=;
len=strlen(s+);
f[]=;
f[]=;
for(i=;i<=len;++i){
j=f[i-];
while(j&&s[j]!=s[i-]) j=f[j];
f[i]=j+;
} for(i=;i<len;++i){
for(j=;j<;++j){
if(s[i+]-''==j){
A.a[i][i+]++;
}
else{
k=f[i+];
while(k&&s[k]-''!=j) k=f[k];
A.a[i][k]++;
}
}
}
A.a[len-][len]=; }
int main(){
int i,j,k;
scanf("%lld%lld%lld",&N,&M,&K);
scanf("%s",s+);
init();
matrix ans=qpow(A,N);
LL res=;
for(i=;i<=ans.len;++i){
res+=ans.a[][i];
res%=K;
}
cout<<res<<endl;
return ;
}

bzoj-1009-dp+kmp处理转移矩阵幂的更多相关文章

  1. bzoj 1009 DP 矩阵优化

    原来的DP: dp[i][j]表示长度为i的合法串,并且它的长度为j的后缀是给定串的长度为j的前缀. 转移: i==0 dp[0][0] = 1 dp[0][1~m-1] = 0 i>=1 dp ...

  2. bzoj 1009 DP+矩阵加速

    我们用DP来解决这个问题 W[I,J]表示准考证的第I位,和不吉利的数匹配到了第J位的方案数,这个状态的表示也可以看成 当前到第I位了,准考证的后J位是不吉利的数的前J位,的方案数 那么我们最后的an ...

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

    题目链接:BZOJ - 1009 题目分析 题目要求求出不包含给定字符串的长度为 n 的字符串的数量. 既然这样,应该就是 KMP + DP ,用 f[i][j] 表示长度为 i ,匹配到模式串第 j ...

  4. bzoj 3622 DP + 容斥

    LINK 题意:给出n,k,有a,b两种值,a和b间互相配对,求$a>b$的配对组数-b>a的配对组数恰好等于k的情况有多少种. 思路:粗看会想这是道容斥组合题,但关键在于如何得到每个a[ ...

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

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

  6. BZOJ1009GT考试 DP + KMP + 矩陣快速冪

    @[DP, KMP, 矩陣快速冪] Description 阿申准备报名参加GT考试,准考证号为\(N\)位数\(X_1 X_2 .. X_n(0 <= X_i <= 9)\),他不希望准 ...

  7. BZOJ 1009: [HNOI2008]GT考试( dp + 矩阵快速幂 + kmp )

    写了一个早上...就因为把长度为m的也算进去了... dp(i, j)表示准考证号前i个字符匹配了不吉利数字前j个的方案数. kmp预处理, 然后对于j进行枚举, 对数字0~9也枚举算出f(i, j) ...

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

    题目链接 设f[i][j]为当前是第i位考号.现在匹配到第j位(已有j-1位和A[]匹配)的方案数 因为假如当前匹配j位,如果选择的下一位与A[j+1]不同,那么新的匹配位数是fail[j]而不是0, ...

  9. BZOJ 1009 [HNOI2008]GT考试(矩阵快速幂优化DP+KMP)

    题意: 求长度为n的不含长为m的指定子串的字符串的个数 1s, n<=1e9, m<=50 思路: 长见识了.. 设那个指定子串为s f[i][j]表示长度为i的字符串(其中后j个字符与s ...

随机推荐

  1. Asp.net页面生存周期【转】

    ASP.NET 页面生存周期中的关键事件 要想深入ASP.NET页面编程,就必须了解页面生存周期各个阶段及相关事件.重写相关事件和方法可以使我们更好的控制页面呈现. # 事件或方法 功能 描述 1 I ...

  2. 在CentOS7下从0开始搭建docker并发布tomcat项目

    一切从0开始,我也是个小白: 1.检查你的系统是不是高于3.8的内核,如果没有请升级CentOS7或者Ubuntu 14 #uname -a 2.CentOS7下安装docker #yum -y in ...

  3. Educational Codeforces Round 28

    A. Curriculum Vitae 题目链接:http://codeforces.com/contest/846/problem/A 题目意思:给你一个只包含0-1的数组,现在要求去可以去掉一些元 ...

  4. centos 系统软件包管理 yum 本地yum配置 扩展源epel rpm 清除yum缓存 yum provides "*/vim" 第十节课

    centos  系统软件包管理  yum 本地yum配置  扩展源epel  rpm  清除yum缓存  yum provides "*/vim"   第十节课 你不能保证可逆化操 ...

  5. git-【十】忽略文件

    1.在Git工作区的根目录下创建一个特殊的.gitignore文件,然后把要忽略的文件名填进去,Git就会自动忽略这些文件. 不需要从头写.gitignore文件,GitHub已经为我们准备了各种配置 ...

  6. nodejs通过代理(proxy)发送http请求(request)

    有可能有这样的需求,需要node作为web服务器通过另外一台http/https代理服务器发http或者https请求,废话不多说直接上代码大家都懂的: var http = require('htt ...

  7. 禁止或强制使用堆分配---《C++必知必会》 条款34

    有时候,指明一些特定类的对象不应该被分配到堆(heap)上是个好主意.通常这是为了确保该对象的析构函数一定会得到调用.维护对象本身(body object)的引用计数的句柄对象(handle obje ...

  8. MySQL中特有的函数If函数

    上面我们已经知道了case函数可以实现逻辑判断,可以是很复杂的逻辑判断,但是如果我们只想实现的是如果这个条件成立就返回A否则就返回B这样简单的逻辑如果用case的话,未免复杂了.我们可以使用if函数来 ...

  9. (25)HttpClient session

    session概述 session机制 session机制是一种服务器端的机制,服务器使用一种类似于散列表的结构(也可能就是使用散列表)来保存信息. 当程序需要为某个客户端的请求创建一个session ...

  10. 2017-2018 ACM-ICPC Latin American Regional Programming Contest Solution

    A - Arranging tiles 留坑. B - Buggy ICPC 题意:给出一个字符串,然后有两条规则,如果打出一个辅音字母,直接接在原字符串后面,如果打出一个元音字母,那么接在原来的字符 ...