Problem 1009. -- [HNOI2008]GT考试

1009: [HNOI2008]GT考试

Time Limit: 1 Sec  Memory Limit: 162 MB
Submit: 3773  Solved: 2314
[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]=a0*dp[i-1][0]+a1*dp[i-1][1]+a2*dp[i-1][2]+a3*dp[i-1][3]+.......an*dp[i-1][m-1];
 最终有ans=dp[n][0]+dp[n][1]+dp[n][2]+....dp[n][m-1];
dp[i][j]的意思是前i个数组元素的后缀有j个和所要匹配的字符串相同。
首先说明这个递推关系式是正确的:将所有合法的号码按   字符串的尾缀与不合法字符串的前缀  相同元素的个数分类,满足不重不漏关系,所以DP是对的。
然后关系式为线性关系,所以可以用矩阵快速幂来计算。
剩下的问题就是如何求得a0,a1,a2....an(系数矩阵)。
进行一遍for循环范围为i=0----m-1,可以知道i只能对i+1之前的元素产生影响,然后再进行填数字。再由KMP进行确定系数。
 
 
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n,m,mod;
int next[],num[];
void get(){
    int i=,j=-;
    next[]=-;
    while(i<m){
        if(j==-||num[i]==num[j]) next[++i]=++j;
        else j=next[j];
    }
}
struct node{
   int mx[][];
   node(){memset(mx,,sizeof(mx));}
}a;
node mult(const node &a,const node &b){
   node c;
   for(int i=;i<m;++i)
    for(int j=;j<m;++j)
    for(int k=;k<m;++k)
    c.mx[i][j]=(c.mx[i][j]+a.mx[i][k]*b.mx[k][j])%mod;
   return c;
}
node ksm(node a,int k){
    node r;
    for(int i=;i<m;++i)
        r.mx[i][i]=;
    while(k){
        if(k&) {r=mult(r,a);k|=;}
        k>>=;
        a=mult(a,a);
    }
    return r;
}
int main(){
   scanf("%d%d%d",&n,&m,&mod);
   getchar();
   for(int i=;i<m;++i) num[i]=getchar()-'';
   get();
   for(int i=;i<m;++i)  //进行第i个元素填充
   for(int j=;j<=;++j){ //若第i个元素为j
    int tmp=i;              //这里首先假设后缀满足了i个,然后对i个位置(数组元素从0开始,所以比较的时候还是num[tmp]而不是num[tmp+1])填充j
    while(tmp!=-&&j!=num[tmp]) tmp=next[tmp];  //若是不相同,就向前找。
    if(tmp==-) ++a.mx[i][];   //如果未找到匹配的位置,则dp[i+1][0]的系数a[i][0]要加1
    else ++a.mx[i][tmp+];  //可以转移到tmp+1的位置(若开始就匹配,就表示可以转移到他的下一个位置,系数加1)
   }//系数矩阵显然是个方阵,第i行第j列表示前一个后缀满足i个转移到后一个后缀满足j个的系数(从而也可以知道系数矩阵第一行起初就是dp[1][0],dp[1][1]...dp[1][m])
   a=ksm(a,n);
   int ans=;
   for(int i=;i<m;++i)
    ans=(ans+a.mx[][i])%mod;
   printf("%d\n",ans);
}
 
 
 

BZOJ1009 矩阵快速幂+DP+KMP的更多相关文章

  1. codeforces 691E 矩阵快速幂+dp

    传送门:https://codeforces.com/contest/691/problem/E 题意:给定长度为n的序列,从序列中选择k个数(可以重复选择),使得得到的排列满足xi与xi+1异或的二 ...

  2. P1357 花园 (矩阵快速幂+ DP)

    题意:一个只含字母C和P的环形串 求长度为n且每m个连续字符不含有超过k个C的方案数 m <= 5  n <= 1e15 题解:用一个m位二进制表示状态 转移很好想 但是这个题是用矩阵快速 ...

  3. Codeforces 576D Flights for Regular Customers 矩阵快速幂+DP

    题意: 给一个$n$点$m$边的连通图 每个边有一个权值$d$ 当且仅当当前走过的步数$\ge d$时 才可以走这条边 问从节点$1$到节点$n$的最短路 好神的一道题 直接写做法喽 首先我们对边按$ ...

  4. COJ 1208 矩阵快速幂DP

    题目大意: f(i) 是一个斐波那契数列 , 求sum(f(i)^k)的总和 由于n极大,所以考虑矩阵快速幂加速 我们要求解最后的sum[n] 首先我们需要思考 sum[n] = sum[n-1] + ...

  5. Codeforces 954 dijsktra 离散化矩阵快速幂DP 前缀和二分check

    A B C D 给你一个联通图 给定S,T 要求你加一条边使得ST的最短距离不会减少 问你有多少种方法 因为N<=1000 所以N^2枚举边数 迪杰斯特拉两次 求出Sdis 和 Tdis 如果d ...

  6. BZOJ1009: [HNOI2008]GT考试 (矩阵快速幂 + DP)

    题意:求一个长度为n的数字字符串 (n <= 1e9) 不出现子串s的方案数 题解:用f i,j表示长度为i匹配到在子串j的答案 用kmp的失配函数预处理一下 然后这个转移每一个都是一样的 所以 ...

  7. Codeforces 989E A Trance of Nightfall 矩阵快速幂+DP

    题意:二维平面上右一点集$S$,共$n$个元素,开始位于平面上任意点$P$,$P$不一定属于$S$,每次操作为选一条至少包含$S$中两个元素和当前位置$P$的直线,每条直线选取概率相同,同一直线上每个 ...

  8. bzoj2004 矩阵快速幂优化状压dp

    https://www.lydsy.com/JudgeOnline/problem.php?id=2004 以前只会状压dp和矩阵快速幂dp,没想到一道题还能组合起来一起用,算法竞赛真是奥妙重重 小Z ...

  9. [BZOJ1009] [HNOI2008] GT考试(KMP+dp+矩阵快速幂)

    [BZOJ1009] [HNOI2008] GT考试(KMP+dp+矩阵快速幂) 题面 阿申准备报名参加GT考试,准考证号为N位数X1X2-.Xn,他不希望准考证号上出现不吉利的数字.他的不吉利数学A ...

随机推荐

  1. maven过滤配置文件

    第一种方式, 解决maven打包时,会编译特定文件导致文件不可用maven打包时,过滤不编译文件类型 <plugin>    <groupId>org.apache.maven ...

  2. 【Python】在Pycharm中安装爬虫库requests , BeautifulSoup , lxml 的解决方法

    BeautifulSoup在学习Python过程中可能需要用到一些爬虫库 例如:requests BeautifulSoup和lxml库 前面的两个库,用Pychram都可以通过 File--> ...

  3. Linux硬盘分区知识

    前言 硬盘使用前,一般要分区,格式化(创建文件系统)<== 存放数据 类比,房子使用前,一般要隔断,装修,买家具,再住人. 分区 一块硬盘: 主分区.扩展分区.逻辑分区 主分区+扩展分区的数量& ...

  4. 使用nodejs + wecharty打造你的个人微信机器人

    开源地址:https://github.com/isnl/wechat-robot 注: 从2017年6月下旬开始,使用基于web版微信接入方案存在大概率的被限制登陆的可能性. 主要表现为:无法登陆W ...

  5. Vue项目开发流程(自用)

    一.配置开发环境 1.1 安装Node.js npm集成在Node中,检查是否安装完成:node -v 1.2 安装cnpm(淘宝镜像) npm install -g cnpm,检查安装是否完成:cn ...

  6. oracle查询当前系统时间前10天的数据

    select * from eo_c_order t where t.create_time>systimestamp-interval'1'day; 转载于:https://www.cnblo ...

  7. INTERVIEW #5

    笔试 150min,3题,每题100分,自己果然还是个蒟蒻呢~ 最近状态好差,虽然做了一些题,但还是考得稀烂,大概有几点需要加强: 独立做题,不要一边看板子一边写代码,更不要一开始就看题解: 对之前研 ...

  8. Arduino入门简介

    先说Arduino是什么? 1.一个平台,开源电子原型平台,包含小板子(UNO开发板.PRO Mini板登)和电脑上安装的软件(IDE). 2.能通过传感器(红外.温度.超声波传感器...)等来感知环 ...

  9. 基于thinkphp3.2.3开发的CMS内容管理系统(二)- Rbac用户权限

    基于thinkphp3.2.3开发的CMS内容管理系统 thinkphp版本:3.2.3 功能: --分类栏目管理 --文章管理 --商品管理 --用户管理 --角色管理 --权限管理 --友情链接管 ...

  10. RabbitMQ的使用(一)- RabbitMQ服务安装

    RabbitMQ的使用(一)- RabbitMQ服务安装 作者:markjiang7m2 原文地址:https://www.cnblogs.com/markjiang7m2/p/12769627.ht ...