可惜没如果=_=
时光的河入海流

 

1009: [HNOI2008]GT考试

Time Limit: 1 Sec  Memory Limit: 162 MB
Submit: 4065  Solved: 2475
[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

 

很久以前就开始写了,写了很久,到现在才懵懵懂懂的搞好

下面是借用的题解,事实证明我的KMP还需加强!

http://blog.csdn.net/loi_dqs/article/details/50897662

 

 1 #include "bits/stdc++.h"
 2 using namespace std;
 3 typedef long long LL;
 4 const int MAX=50;
 5 int n,m,mod;
 6 char s[MAX];
 7 int next[MAX];
 8 struct Mat{
 9     int x,y;
10     int mat[MAX][MAX];
11     Mat(){x=y=0;memset(mat,0,sizeof(mat));}
12     void init(int xx,int yy){
13         int i,j;
14         x=xx;y=yy;
15         for (i=1;i<=min(x,y);i++)
16             mat[i][i]=1;
17     }
18     Mat operator * (const Mat &tt) {
19         int i,j,k;
20         Mat an;
21         an.x=x,an.y=tt.y;
22         for (k=1;k<=y;k++){
23             for (i=1;i<=an.x;i++){
24                 if (mat[i][k]){
25                     for (j=1;j<=an.y;j++){
26                         an.mat[i][j]=(an.mat[i][j]+mat[i][k]*tt.mat[k][j])%mod;
27                     }
28                 }
29             }
30         }
31         return an;
32     }
33 }cc;
34 Mat ksm(Mat tt,int x){
35     Mat an;an.init(tt.x,tt.y);
36     while (x){
37         if (x%2) an=tt*an;
38         tt=tt*tt;
39         x>>=1;
40     }
41     return an;
42 }
43 void get_next(){
44     int i,j;
45     j=0;next[0]=0;
46     for (i=1;i<m;i++){
47         while (j && s[i]!=s[j]) j=next[j];
48         next[i+1]=(s[i]==s[j]?++j:0);
49     }
50 }
51 int main(){
52     freopen ("gt.in","r",stdin);
53     freopen ("gt.out","w",stdout);
54     int i,j,ans=0;
55     scanf("%d%d%d\n",&n,&m,&mod);
56     gets(s);get_next();
57     cc.x=cc.y=m;
58     for (i=1;i<=m;i++){
59         for (j=0;j<=9;j++){
60             int zt=i-1;
61             while (zt && j!=(s[zt]-'0')) zt=next[zt];
62             if (j==(s[zt]-'0')) zt++;
63             if (zt!=m){
64                 cc.mat[zt+1][i]=(cc.mat[zt+1][i]+1)%mod;
65             }
66         }
67     }
68     cc=ksm(cc,n);
69     for (i=1;i<=m;i++){
70         ans=(ans+cc.mat[i][1])%mod;
71     }
72     printf("%d\n",ans);
73     return 0;
74 }

 

posted on 2017-09-06 14:15  珍珠鸟  阅读(109)  评论(0编辑  收藏  举报