题目
阿申准备报名参加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
OUTPUT
81
解题报告
这道题一开始真心没有什么思路,后来我跟两个dalao一起商(luan)谈(gao)了一个来小时,终于搞了出来= =
首先,我们我们考虑两个串(从短到长)
第一个串为不断增加的准考证号,第二个串为不吉利的号码,第一个串的后缀与第二个串的前缀为重复部分,那么我们很容易得出递推关系
先扯出来,考虑两个集合,一个集合为不吉利的号码,一个集合为吉利的号码。我们只考虑后缀(正确性显然,因为长度长的串一定是由长度短的串递推过来的,所以如果前面有不吉利串,一定被前面的串卡掉了),当后缀包含了m个不吉利串,该串一定是不吉利的。那么,后缀包含0~m-1个不吉利串的前缀的串一定是吉利的。所以,我们把求不吉利的串 转化为 求 后缀包含不吉利串0~m-1 的 串 的 方案数
然而与字符串有啥关系?
考虑这样一个不吉利串
123124
当你的后缀带了2时,你怎么知道你的后几位是12还是12312?所以,加一位不吉利数不代表直接在后面加了一位。
那么,问题来了,如何表示这些奇(chun)奇(de)怪(bu)怪(xing)的转移?
考虑一个递推矩阵,设dp[i][j]为第i个号码匹(zhuan)配(yi)到第j个不吉利数字的方案数,设a[k][i]为k位后加一个数转移到j的方案数,我们可以轻易的得出递推关系:
dp[i][j]=∑dp[i-1][k]*a[k][j]
用KMP构造初始矩阵,矩阵快速幂得到递推结果。
为什么是矩阵快速幂?
这个问题很简单。我们知道,矩阵乘是这样写的:
那么问题就简单起来了,考虑一个3*3的初始矩阵,第i行,第j列表示从第i位加一个数字转移到第j为数字的方案数,那么以该矩阵的平方的第一行第一列的数为例,(设初始矩阵为a,该矩阵为x):
x[1][1]=a[1][1]×a[1][1]+a[1][2]×a[2][1]+a[1][3]×a[3][1];
因为是平方得到的矩阵,所以代表了转移两步的状态,我们知道,x[1][1]代表了从第一位经两步转移到第一位的方案数,由加法原理可知:
1->1(经两步)=(1->1->1)+(1->2->1)+(1->3->1)
而又由乘法原理可知:
1->2->1=(1->2)×(2->1)
那么正确性就很显然了,由矩阵快速幂的递推关系可知,最终结果即为第一行的数的和
至于KMP,把10个数字扔进去乱搞就是了= =
记得要模k= =
ps:2017-6-14 晚 讲题用题解
pss:调矩阵快调死了= =,最后发现初始矩阵求错了= =