【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位的数。 100%数据N<=10^9,M<=20,K<=1000 40%数据N<=1000 10%数据N<=6
【Output】
第一行输入N,M,K.接下来一行输入M位的数。 100%数据N<=10^9,M<=20,K<=1000 40%数据N<=1000 10%数据N<=6
【Sample Input】
4 3 100
111
【Sample Output】
81
【Solution】
一开始没有想到。参考了iwtwiioi大神的blog和cjk_My steps的blog用KMP求出递推矩阵,然后求解即可。
代码如下:
/**************************************************************
Problem: 1009
User: llgyc
Language: Pascal
Result: Accepted
Time:56 ms
Memory:232 kb
****************************************************************/
type matrix = array[0..25,0..25] of longint;
var n,m,mo,i,j,p,t,sum:longint;
pre:array[0..25] of longint;
ans,tmp:matrix;
s:string;
procedure mul(var a,b,ans:matrix);
var i,j,k:longint;
c:matrix;
begin
fillchar(c,sizeof(c),0);
for i:=0 to m-1 do
for j:=0 to m-1 do
for k:=0 to m-1 do
c[i,j]:=(c[i,j]+a[i,k]*b[k,j]) mod mo;
ans:=c;
end;
begin
readln(n,m,mo); readln(s);
//kmp
fillchar(pre,sizeof(pre),0);
p:=0; pre[1]:=0;
for i:=2 to m do begin
while (p>0) and (s[p+1]<>s[i]) do p:=pre[p];
if s[p+1]=s[i] then inc(p);
pre[i]:=p;
end;
//make_matrix
fillchar(tmp,sizeof(tmp),0); fillchar(ans,sizeof(ans),0);
for i:=0 to m-1 do
for j:=0 to 9 do begin
t:=i;
while (t>0) and (ord(s[t+1])-ord('0')<>j) do t:=pre[t];
if ord(s[t+1])-ord('0')=j then inc(t);
if t<>m then tmp[t,i]:=(tmp[t,i]+1) mod mo;
end;
for i:=0 to m-1 do ans[i,i]:=1;
while (n>0) do begin
if n mod 2=1 then mul(ans,tmp,ans);
mul(tmp,tmp,tmp);
n:=n>>1;
end;
//count
sum:=0;
for i:=0 to m-1 do sum:=(sum+ans[i,0]) mod mo;
writeln(sum);
end.