[HNOI2008]GT考试

1009: [HNOI2008]GT考试

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

设$dp[i][j]$表示前i个字符,且后缀为不吉利数字的前缀的最长长度为j的方案数,那么显然$ans = \sum_{i=1}^{m-1}\ dp[n][i]$

设$num[i][j]$为在长度为$i$的不吉利数字的前缀后加一个数使得后缀为不吉利数字的前缀的最长长度为$j$的方案数,$num$数组可以用kmp求出来

转移为$dp[k][j] = \sum_{i = 1}^{m - 1}\ dp[k -1][i] * num[i][j]$

对于同一串不吉利数字$num$数组为常数,那么可以利用矩阵加速递推

#include <cstdio>
#include <cstring>
const int maxm = 25;
int mod;
struct matrix{
    int n, m, num[maxm][maxm];
    matrix(){}
    matrix(int _n, int _m){
        n = _n;
        m = _m;
        memset(num, 0, sizeof num);
    }
    matrix operator * (const matrix &a){
        matrix b(n, a.m);
        for(int i = 0; i < n; i++)
            for(int j = 0; j < a.m; j++)
                for(int k = 0; k < m; k++)
                    (b.num[i][j] += num[i][k] * a.num[k][j]) %= mod;
        return b;
    }
};
matrix ksm(matrix a, int b){
    matrix s(a.m, a.m);
    for(int i = 0; i < s.m; i++)
        s.num[i][i] = 1;
    while(b){
        if(b & 1) s = s * a;
        b >>= 1;
        a = a * a;
    }
    return s;
}
int n, m;
char A[maxm];
int p[maxm];
int main(){
    scanf("%d %d %d", &n, &m, &mod);
    scanf("%s", A + 1);
    p[1] = 0;
    for(int j = 0, i = 2; i <= m; i++){
        while(A[i] != A[j + 1] && j) j = p[j];
        if(A[i] == A[j + 1]) j++;
        p[i] = j;
    }
    matrix ans(1, m), zy(m, m);
    for(int i = 0; i < m; i++)
        for(int j = ‘0‘; j <= ‘9‘; j++){
            int k = i;
            while(k && A[k + 1] != j) k = p[k];
            if(A[k + 1] == j) k++;
            if(k != m) zy.num[i][k]++;
        }
    ans.num[0][0] = 1;
    ans = ans * ksm(zy, n);
    int aa = 0;
    for(int i = 0; i < m; i++)
        (aa += ans.num[0][i]) %= mod;
    printf("%d\n", aa);
    return 0;
}
时间: 2024-08-05 14:58:45

[HNOI2008]GT考试的相关文章

BZOJ_1009_[HNOI2008]_GT考试_(动态规划+kmp+矩阵乘法优化+快速幂)

描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1009 字符串全部由0~9组成,给出一个串s,求一个长度为n的串,不包含s的种类有多少. 分析 第一眼以为是组合.然后更滑稽的是用错误的方法手算样例居然算出来是对的...我数学是有多差... 题解也是看了好半天,有点难理解. 感觉PoPoQQQ神犇讲得还是比较清楚的.传送门:http://blog.csdn.net/popoqqq/article/details/40188173 我们用dp[

BZOJ 1009: [HNOI2008]GT考试 AC自动机+矩阵快速幂

经典题目了....虽然只有一个不能出现的字符串,但还是写了ac自动机 1009: [HNOI2008]GT考试 Time Limit: 1 Sec  Memory Limit: 162 MB Submit: 2051  Solved: 1257 [Submit][Status][Discuss] Description 阿申准备报名参加GT考试,准考证号为N位数X1X2....Xn(0<=Xi<=9),他不希望准考证号上出现不吉利的数字.他的不吉利数学A1A2...Am(0<=Ai<

BZOJ 1009: [HNOI2008]GT考试

1009: [HNOI2008]GT考试 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 3437  Solved: 2110[Submit][Status][Discuss] Description 阿申准备报名参加GT考试,准考证号为N位数X1X2....Xn(0<=Xi<=9),他不希望准考证号上出现不吉利的数字.他的不吉利数学A1A2...Am(0<=Ai<=9)有M位,不出现是指X1X2...Xn中没有恰好一段等于A1A2..

题解:BZOJ 1009 HNOI2008 GT考试 KMP + 矩阵

原题描述: 阿申准备报名参加GT考试,准考证号为N位数 X1X2....Xn(0<=Xi<=9),他不希望准考证号上出现不吉利的数字.他的不吉利数学A1A2...Am(0<=Ai& lt;=9)有M位,不出现是指X1X2...Xn中没有恰好一段等于A1A2...Am. A1和X1可以为0 分析: 吐槽:这道题的细节问题差点坑死我. 一开始这道题想了个DP,但是状态转移太恶心. 那我们换一个思路,先用KMP构造出A的一个自动机. 然后这道题就转化成了在自动机上跑啊跑,跑N条边都没跑

BZOJ1009 [HNOI2008]GT考试 矩阵

题目 [bzoj1009][HNOI2008]GT考试 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位的数. 100%数据N<=10^9,M<=20,K<=1000 40%数据N<

【BZOJ1009】[HNOI2008]GT考试 next数组+矩阵乘法

[BZOJ1009][HNOI2008]GT考试 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 阿申想知

BZOJ 1009: [HNOI2008]GT考试( dp + 矩阵快速幂 + kmp )

写了一个早上...就因为把长度为m的也算进去了... dp(i, j)表示准考证号前i个字符匹配了不吉利数字前j个的方案数. kmp预处理, 然后对于j进行枚举, 对数字0~9也枚举算出f(i, j)表示dp(x-1, j)对dp(x, i)的贡献.然后用矩阵快速幂就可以了. 时间复杂度O(M3logN + M) ------------------------------------------------------------------- #include<bits/stdc++.h>

bzoj 1009: [HNOI2008]GT考试 -- KMP+矩阵

1009: [HNOI2008]GT考试 Time Limit: 1 Sec  Memory Limit: 162 MB 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<=

bzoj1009 [HNOI2008] GT考试 矩阵乘法+dp+kmp

1009: [HNOI2008]GT考试 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 4542  Solved: 2815[Submit][Status][Discuss] Description 阿申准备报名参加GT考试,准考证号为N位数X1X2....Xn(0<=Xi<=9),他不希望准考证号上出现不吉利的数字.他的不吉利数学A1A2...Am(0<=Ai<=9)有M位,不出现是指X1X2...Xn中没有恰好一段等于A1A2..