• [HNOI2008]GT考试


    Description

    阿申准备报名参加GT考试,准考证号为N位数 X1X2....Xn(0<=Xi<=9),他不希望准考证号上出现不吉利的数字。他的不吉利数学A1A2...Am(0<=Ai& lt;=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

    阿申想知道不出现不吉利数字的号码有多少种,输出模K取余的结果.

    Sample Input

    4 3 100
    111

    Sample Output

    81
     
     
     
     
     
     
     神题碰上弱菜.....
    动态规划啊,但数据这么大怎么想得到是动态规划呢,太弱了......
    f[i][j]表示准考证前i位中后j位为不吉利的数字的前j位。
    转移方程:
        
     

     

    因此就可以使用矩阵乘法加速了!

    a[k][j]表示f[i-1][k]转为f[i][j]的方法数,这步可以用KMP解决。

    ans+=f[0][j] (j=0;j<m;++j);

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<string.h>
     5 #include<fstream>
     6 using namespace std;
     7 //ifstream fin("fin.in");
     8 
     9 string s;
    10 int n,m,mod,ans=0,pi[25];
    11 int f[25][25]={0},a[25][25],b[25][25];
    12 
    13 void Work(int x){
    14      if(x>3) Work(x/2);
    15      if(x==1) return ;
    16      
    17      memset(a,0,sizeof(a));
    18      for(int i=0;i<m;++i)
    19      for(int j=0;j<m;++j)
    20      for(int k=0;k<m;++k)
    21      a[i][j]=(a[i][j]+f[i][k]*f[k][j])%mod;
    22      
    23      memcpy(f,a,sizeof(a));
    24      
    25      if(x%2)
    26      {
    27        memset(a,0,sizeof(a));
    28        for(int i=0;i<m;++i)
    29        for(int j=0;j<m;++j)
    30        for(int k=0;k<m;++k)
    31        a[i][j]=(a[i][j]+f[i][k]*b[k][j])%mod;
    32        
    33        memcpy(f,a,sizeof(f));
    34             }
    35      }
    36 
    37 void Kmp(){
    38      for(int i=2;i<s.size();++i)
    39      {
    40        int x=pi[i-1];      
    41        while(s[i]!=s[x+1]&&x!=0) x=pi[x];                       
    42        if(s[i]==s[x+1]) pi[i]=x+1;                     
    43              }
    44      }
    45 
    46 void Prepare(){
    47      for(int i=0;i<s.size()-1;++i)
    48      for(int j=0;j<=9;++j)
    49      {
    50        int x=i;                     //小心观看 
    51        while(x!=0&&j!=s[x+1]-'0') x=pi[x];
    52        if(j==s[x+1]-'0') f[i][x+1]++;
    53        else f[i][0]++; 
    54              }
    55      memcpy(b,f,sizeof(f));
    56      }
    57 
    58 int main()
    59 {
    60     cin>>n>>m>>mod>>s;
    61     s=" "+s;
    62     Kmp();
    63     
    64     Prepare();
    65     
    66     Work(n);
    67     
    68     for(int i=0;i<m;++i) ans+=f[0][i];
    69     
    70     cout<<ans%mod<<endl;
    71    // system("pause");
    72     return 0;
    73     
    74     }
     
  • 相关阅读:
    oracle的安装与plsql的环境配置
    Working with MSDTC
    soapui-java.lang.Exception Failed to load url
    Oracle 一个owner访问另一个owner的table,不加owner
    Call API relation to TLS 1.2
    Call API HTTP header Authorization: Basic
    VS2008 .csproj cannot be opened.The project type is not supported by this installat
    The changes couldn't be completed.Please reboot your computer and try again.
    Create DB Table View Procedure
    DB Change
  • 原文地址:https://www.cnblogs.com/noip/p/2962560.html
Copyright © 2020-2023  润新知