zoukankan      html  css  js  c++  java
  • BZOJ-1009 [HNOI2008]GT考试(KMP+矩阵快速幂)

    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,&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
    ",ans);
    73     return 0;
    74 }
    未来是什么样,未来会发生什么,谁也不知道。 但是我知道, 起码从今天开始努力, 肯定比从明天开始努力, 要快一天实现梦想。 千里之行,始于足下! ——《那年那兔那些事儿》
  • 相关阅读:
    用 Flask 来写个轻博客
    Django 博客开发教程目录索引
    动态规划问题
    Java课程目录
    React&Vue
    Node.js
    Chrome Input框老是有输入记录的终极解决方案
    php中&运算符的理解与使用
    服务器压测、并发数、配置与资源消耗的关系研究
    定时任务被执行两遍,如何处理?
  • 原文地址:https://www.cnblogs.com/keximeiruguo/p/7484561.html
Copyright © 2011-2022 走看看