1009: [HNOI2008]GT考试

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

 
 
 
  1 #include<iostream>
  2 #include<string>
  3 #define M 25 
  4 using namespace std;
  5 
  6 int n,m,d;string s;
  7 int next[M]={0},a[M][M]={0};
  8 
  9 void Next(){
 10      for(int i=2;i<s.size();++i)
 11      {
 12        int j=i-1;
 13        while(j!=0)
 14        {
 15          if(s[i]==s[next[j]+1]) break;
 16          j=next[j];
 17               }
 18        if(j==0) next[i]=0;
 19        else next[i]=next[j]+1;
 20              }
 21      
 22      return ;
 23      
 24      }
 25 
 26 void Init(){
 27      for(int i=0;i<m;++i)
 28      {
 29        int j=i,sum=1;
 30        a[i][j+1]=1;
 31        bool p[10]={0};
 32        p[s[j+1]-'0']=1;
 33        
 34        while(j!=0)
 35        {
 36          j=next[j];
 37          if(p[s[j+1]-'0']==0)
 38          {
 39            a[i][j+1]=1;
 40            p[s[j+1]-'0']=1;
 41            sum++;
 42                            }        
 43                   } 
 44       a[i][0]=10-sum;         
 45              }
 46      }
 47 
 48 void Multiply(int re[][M],int x[][M],int y[][M]){
 49     for(int i=0;i<m;++i)
 50     for(int j=0;j<m;++j)
 51     for(int k=0;k<m;++k)
 52     {re[i][j]+=x[i][k]*y[k][j];re[i][j]%=d;}
 53     return ;
 54     }
 55 
 56 void Solve(int re[][M],int x[][M],int t){
 57     if(t==1)
 58     {
 59       for(int i=0;i<m;++i)
 60       for(int j=0;j<m;++j)
 61       re[i][j]=x[i][j];
 62       return ;
 63             }
 64             
 65     int y[M][M]={0},z[M][M]={0};        
 66     Solve(y,x,t/2);
 67     
 68     
 69     
 70     Multiply(z,y,y);
 71     
 72     if(t%2==1)
 73     Multiply(re,z,x);
 74     else
 75     {
 76         for(int i=0;i<m;++i)
 77         for(int j=0;j<m;++j)
 78         re[i][j]=z[i][j];
 79 
 80         } 
 81     return ;
 82     }
 83 
 84 int main()
 85 {
 86     cin>>n>>m>>d;
 87     cin>>s;
 88     s=" "+s;
 89     
 90     Next();
 91     
 92     Init();
 93     
 94     int an[M]={0},ans[M]={0};
 95     an[0]=9;
 96     an[1]=1;
 97     
 98     int b[M][M]={0};
 99     Solve(b,a,n-1);
100     
101     
102     
103     for(int i=0;i<m;++i)
104     for(int j=0;j<m;++j)
105     {ans[i]+=an[j]*b[j][i];ans[i]%=d;}
106     
107     
108     
109     for(int i=1;i<m;++i)
110     {ans[0]+=ans[i];ans[0]%=d;}
111     
112     
113     cout<<ans[0]<<endl;
114     
115   //  system("pause"); 
116     
117     } 

 

posted on 2017-11-29 11:37  怡红公子  阅读(195)  评论(0编辑  收藏  举报