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
111
Sample Output
81
这道题是一个KMP+DP+矩阵快速幂,设dp[i][j]表示匹配到第i个数时匹配到第j个不吉利数字,r[j][k]表示dp[i][j]后添加一位数字可以转到状态k的次数,然后对r进行n次矩阵快速幂后统计第一行之和就是答案,下面是程序:#include<stdio.h>
#include<iostream>
using namespace std;
char a[25];
int n,m,mod,next[25],s[25][25],r[25][25];
void read(int &s){
s=0;
char c=getchar();
while(c<'0'||c>'9'){
c=getchar();
}
while(c>='0'&&c<='9'){
s*=10;
s+=c-'0';
c=getchar();
}
}
void read(char *a){
char c=getchar();
int l=0;
while(c<'0'||c>'9'){
c=getchar();
}
while(c>='0'&&c<='9'){
a[l++]=c;
c=getchar();
}
a[l]='\0';
}
void mul(int (*s)[25],int (*a)[25],int (*b)[25]){
int i,j,k,tp[25][25];
for(i=0;i<m;i++){
for(j=0;j<m;j++){
tp[i][j]=0;
for(k=0;k<m;k++){
tp[i][j]+=a[i][k]*b[k][j];
tp[i][j]%=mod;
}
}
}
for(i=0;i<m;i++){
for(j=0;j<m;j++){
s[i][j]=tp[i][j];
}
}
}
int main(){
read(n);
read(m);
read(mod);
read(a+1);
int i,j;
for(i=2,j=0;i<=m;i++){
while(j>0&&a[j+1]!=a[i]){
j=next[j];
}
if(a[j+1]==a[i]){
++j;
}
next[i]=j;
}
for(i=0;i<m;i++){
for(j=0;j<=9;j++){
int t=i;
while(t>0&&a[t+1]-'0'!=j){
t=next[t];
}
if(a[t+1]-'0'==j){
t++;
}
if(t!=m){
r[i][t]++;
r[i][t]%=mod;
}
}
}
s[0][0]=1;
while(n){
if(n&1){
mul(s,s,r);
}
mul(r,r,r);
n>>=1;
}
int ans=0;
for(i=0;i<m;i++){
ans+=s[0][i];
ans%=mod;
}
printf("%d\n",ans);
return 0;
}
#include<stdio.h>
#include<iostream>
using namespace std;
char a[25];
int n,m,mod,next[25],s[25][25],r[25][25];
void read(int &s){
s=0;
char c=getchar();
while(c<'0'||c>'9'){
c=getchar();
}
while(c>='0'&&c<='9'){
s*=10;
s+=c-'0';
c=getchar();
}
}
void read(char *a){
char c=getchar();
int l=0;
while(c<'0'||c>'9'){
c=getchar();
}
while(c>='0'&&c<='9'){
a[l++]=c;
c=getchar();
}
a[l]='\0';
}
void mul(int (*s)[25],int (*a)[25],int (*b)[25]){
int i,j,k,tp[25][25];
for(i=0;i<m;i++){
for(j=0;j<m;j++){
tp[i][j]=0;
for(k=0;k<m;k++){
tp[i][j]+=a[i][k]*b[k][j];
tp[i][j]%=mod;
}
}
}
for(i=0;i<m;i++){
for(j=0;j<m;j++){
s[i][j]=tp[i][j];
}
}
}
int main(){
read(n);
read(m);
read(mod);
read(a+1);
int i,j;
for(i=2,j=0;i<=m;i++){
while(j>0&&a[j+1]!=a[i]){
j=next[j];
}
if(a[j+1]==a[i]){
++j;
}
next[i]=j;
}
for(i=0;i<m;i++){
for(j=0;j<=9;j++){
int t=i;
while(t>0&&a[t+1]-'0'!=j){
t=next[t];
}
if(a[t+1]-'0'==j){
t++;
}
if(t!=m){
r[i][t]++;
r[i][t]%=mod;
}
}
}
s[0][0]=1;
while(n){
if(n&1){
mul(s,s,r);
}
mul(r,r,r);
n>>=1;
}
int ans=0;
for(i=0;i<m;i++){
ans+=s[0][i];
ans%=mod;
}
printf("%d\n",ans);
return 0;
}